The JSthisWhat is it?

This in JavaScript is probably a mystery until the system knows it.

You’ve probably seen hundreds of times in Vue like const that = this; The expression of

const that = this;
const obj = {
	message: "I'm obj.".printThis: function(){
	    console.log(this);
    },
     printThat: function(){
	    console.log(that); }}; obj.printThis(); obj.printThat();Copy the code

Why do we have to use const that = this; How to get the correct “this”?

For a function (i.e., an object), this refers to the object on which the function was called.

An 🌰

function printThis(){
	console.log(this);
}
const obj = {
	message: "I'm obj.".printThis: printThis
}

printThis();	// equivalent to this.printThis(); This is called in the window context to refer to the object that called the function: window

obj.printThis();	// printThis is called in the context of obj. This refers to the object on which the function was called: obj
Copy the code

So a quick summary: this always refers to the object on which this function is called.

Where does this point inside the constructor? Does it also point to the object calling the constructor?

The constructor is called when the object is instantiated. The call() method is called to refer to the object, so this refers to the object itself. See what you do when you new an object for details.

So we can go back to the question of why we use const that = this; ?

const that = this;
const obj = {
	message: "I'm obj.".printThis: function(){
	    console.log(this);
    },
     printThat: function(){
	    console.log(that); }}; obj.printThis(); obj.printThat();Copy the code

That’s just to save the external this to that, and then call the external this in the function.

This is the object on which this function is called.

How to use this elegantly in JS

In conclusion, we should have a general idea of what this is. Use const that = this; This statement is definitely not elegant, so how do you use this elegantly in a project?

Arrow function

First, we can use this directly through the arrow function, because the arrow function is not bound to the pointer field, which means that the this inside the arrow function is the same as the this outside the arrow function.

console.log(this);	// 1 points to window
const obj = {
	message: "I'm obj.".printThis: function(){
        console.log(this);
    },
    printThisWithArrowFunction: () = > { console.log(this); }
}
obj.printThis();	// 2 here points to obj
obj.printThisWithArrowFunction();	// 3 points to window just like 1 does
Copy the code

So you can use the arrow function to happily solve the problem that this points to different things.

Change the function manuallythis

The JS function provides three methods to manually point to this :call(), apply(), and bind().

We can specify this directly by calling these three methods, so why do we need three methods for this?

methods parameter The return value instructions
call() this, param1, param2, … undefined Call by passing in the this pointer and arguments
apply() this,[param1, param2, …] undefined Pass this to point to andArray parameterYou can call
bind() this, param1, param2, … Function Pass in the this pointer and argumentsReturns the corresponding pointing function

It is easy to see that the three functions do almost the same thing, but their usage is slightly different. For example, 🌰 :

function printThis(a, b){
	console.log(this, a, b);
}
const obj = {
    message: "I'm obj."
}
printThis.call(obj, 1.2);
printThis.apply(obj, [1.2]);	// It is an array
printThis.bind(obj, 1.2) ();// Note that the return is a function, but also need to call the return value
Copy the code

More and more

By now you probably understand how to use this properly. So what’s the use?

Here’s an example of a well-known array clipping: 🌰:

const arr = [1.2.3];
arr.slice(1); // Remove the first slice in which this points to arr!
console.log(arr);	/ / [2, 3]
// How can we use this feature to split non-generic array types?
const obj = {
	0: 1.1: 2.2: 3.length: 3 // Must have the length attribute
};
// Call obj.slice(1) directly; Object prototype does not have this method
This can be done by artificially altering the this pointer to slice
console.log(Array.prototype.slice.call(obj, 1));	// Call this to obj
Copy the code