Who does this represent in JavaScript( Where does this point to?)

Time:2021-4-26

This is a special keyword in many programming languages, such as this in Java and this in JavaScript. So, what are the features and usage of this in JavaScript? How is it defined?

Let’s take a look at the definition of this in ECMAScript Standard Specification

「The this keyword evaluates to the value of the ThisBinding of the current execution context.」
“The value represented by this keyword is thisbinding of the current execution context.”

Then let’s take a look at MDN’s definition of this

「In most cases, the value of this is determined by how a function is called.」
“In most cases, the value of this depends on how the function is called.”

This is an interesting feature of JavaScriptIt’s not fixed, it changes with the execution environmentIt’s roughly as follows

(1) when the function (method) is invoked, the this representation in the method always points to the object when it is invoked at last.

Who does this represent in JavaScript( Where does this point to?)

In the above example, it can be seen that when a variable with the same name as the attribute on the object obj is defined in the global environment, the method called on the object will first search for the required variables, such as name and FN, in the method scope. If it can be found, it will use the value. If it cannot be found, it will search along the function domain chain to the scope obj where the method FN is created, Such a layer by layer network has been found until the top window. But this example is concerned with the direction of this. By printing, it knows that it is pointing to obj, and the calling object method FN is the last object that just happens to be obj, thus corroborate the popular definition of this [always pointing to the object that finally calls the method].

In addition, in this example, some people may wonder why the name in obj method FN is not the name value 123 of obj, but the 2333 of global variable? First of all, we know that we need to access the properties on an object. The specified format is  Obj. PropertiesperhapsObj [property].At this time, the printed name does not have obj, so it will be parsed as a variable. At this time, the name variable will be searched in the scope of FN function. If not, the name variable will be searched up the scope chain(Some people think that when there is no specific calling object, such as obj, this directly points to the window object)。 The scope chain looks like this:obj._proto_===window.prototype===window._proto_According to the scope chain, we finally find the variable name on the object prototype of window, and that’s it!

② In a global environment,Whether in strict mode or not, this points to a global objectIt points to the window object in the browser, and the global object in nodejs points to undefined in the strict mode. Therefore, the global variable defined in the strict mode cannot be called with this;

var num = 123;
console.log(this.num ) ;              // 123
console.log(this.num  === num ) ;        // true
console.log(this === window) ;     // true

In strict mode:

"Use strict" // use strict mode
var num= 123;

function fn() {
    console.log(this);   // undefined
    console.log ( this.num );  //  The error "cannot read property 'num' of undefined" is reported because this is undefined
}

fn();

  ③ In the constructor, this is the instance object created by the constructor.

var name="JavaScript";

 function Student(sName,sAge){
     this.name=sName;
     this.age=sAge;    
     console.log (this);  // Print instance objects student {Name: "Zhang San", 18} and student {Name: "Li Si", 20}
  }    
  
 Var S1 = new student ("Zhang San", 18);
 Var S2 = new student ("Li Si", 20);

Who does this represent in JavaScript( Where does this point to?)

All of the above are about how to find out the object pointed to by this, so that we can use the properties and methods on the object. However, the direction of this can also be manually changed through the call, apply and bind methods. In this way, sometimes the method and attribute on the obj of the object directly re pointed by this can be satisfied, but the original object of the method will not be changed.

Who does this represent in JavaScript( Where does this point to?)

As can be seen from the print in the figure above, call changes the direction of the original OK method this from obj to newobj, so that the OK method can use the properties and methods on the newobj object, while the printout on line 17 shows that the properties and methods on the original obj object have not been destroyed.

The function of call, apply and bind(They are used to expand the scope of function runtime)Finally, by the way, I would like to add some small differences in the writing of the three

1) , bind() method will return a function that takes multiple parameters into a single parameter.

Note: bind (thisarg [, arg1 [, arg2 [,…]]]) transforms a function that takes multiple parameters into a single parameter. The length (number of formal parameters) of the function returned by the bind() method is equal to the number of formal parameters of the original function minus the number of actual parameters in the incoming bind() method (all parameters after the first parameter), because the actual parameters in the incoming bind() method will be bound to the formal parameters of the original function.

2) , apply() method   Receive two parameters, one is the scope of the function (this), the other is the parameter array.

Note:apply([thisObj [,argArray] ])To call a method of an object and replace the current object with another object. If argarray is not a valid array or is not an arguments object, it will result in a typeerror. If neither argarray nor thisobj is provided, the global object will be used as thisobj.

3) , call() method   The first parameter is the same as the apply () method, but the parameters passed to the function must be listed.

Note: Call ([thisobject [, arg1 [, arg2 [,…, argn]]]);, Apply a method of one object to replace the current object with another. The call method can be used to call a method instead of another object. The call method can change the object context of a function from the initial context to the new object specified by thisobj. If the thisobj parameter is not provided, the global object is used for thisobj.

[three methods memory tips] call is like calling to call the required parameters, one by one following thisobj. Apply is like filling out a form to apply for something. Package the required parameters in an array. Bind is to bind the parameters one by one behind thisobj, similar to call, but in the end, bind only returns one function, You also need to call it manually (like the delivery after the courier collects the items).If these three methods are used in the anonymous callback function of the timer, they will destroy the timer, because they will be executed immediately!

Who does this represent in JavaScript( Where does this point to?)

④ It’s said that ES6 is good, so how does this perform in ES6? ES6 brings the arrow function, let developers in front of a flash, not only the code writing more concise and elegant, but also let the function of this erratic with the official designated place!

In the arrowhead function, this is different from the this in the traditional common function. In the ordinary function, this points to the object that is the last calling function (that is, the object being called when the function is called). This of arrow function is inherited by this of outer function when defining arrow function(It’s not really inheritance. It’s a bit like borrowing)In other words, the arrow function itself does not have this. It depends on the this defined by the outer code.This of the arrow function is not determined when it is called, but when it is defined, the object containing the arrow function is its this. In fact, it should also include a search process, as follows:This of the arrow function depends on whether there is a function in the outer layer. If there is, this of the outer function is this of the inner arrow function. If not, this is window

Scenario 1: the outer layer of the arrowhead function is a function. The outer function is called by obj at last, so this points to obj, and the arrow function inherits it.

Who does this represent in JavaScript( Where does this point to?)

Scenario 2: when a method on an object is directly defined as an arrow function, because the outer layer of the arrow function is an object, not a function, this directly points to the window.

Who does this represent in JavaScript( Where does this point to?)

Arrow function brings convenience, but there are also some points to pay attention to, as follows:

① When using call, apply and bind in arrow function, this parameter binding is invalid,This is forced to point to windowAs for the reason, I am not sure. If anyone knows, please let me know in the comments.   

var name="Hello watching me!";
var obj={
    name:"coder4web",
    Arrowfn: () = > {// setting the object property to arrow function directly
            console.log (the result of "this = = newobj" is "+ (this = = newobj));
            console.log (the result of "this = = obj" is "+ (this = = obj));
            console.log(this.name+"--is testing :I'm an arrow function!");
    }
};
var newObj={
    name:123,
    ok:function(){
        console.log (ha ha ha ha ~ ~);
    }
};
// obj.arrowFn.apply();
// obj.arrowFn.apply(undefined);
// obj.arrowFn.apply(null);
obj.arrowFn.apply (newObj);  // The effect of these four methods is the same

Who does this represent in JavaScript( Where does this point to?)

② Arrow functions cannot be used as constructors, because arrow functions are anonymous functions, and constructors are named functions. Therefore, arrow functions cannot use new, and arrow functions cannot use argument. There is no prototype attribute.

var Student=(name)=>{
    this.name=name;
}
//Var s = new student ("Li Lei");
// console.log(s);    //Uncaught TypeError: Student is not a constructor
var fn=(x)=>{
    console.log(x);
//     console.log(arguments);  //Uncaught ReferenceError: arguments is not defined
}
// fn(11);
var t1=function(){}
var t2=function teacher(){}
var t3=()=>{}
console.log(t1);
console.log(t1.prototype);
console.log(t2);
console.log(t2.prototype);
console.log(t3);
console.log(t3.prototype);

Who does this represent in JavaScript( Where does this point to?)

At this point, the problem of this point in JavaScript has been explored. Most of the above conclusions are my own summary after reading and thinking. In view of the limited level, it is inevitable to have errors in understanding. If you have a better opinion, you are welcome to make suggestions in the comments area! Thank you for reading~

This article belongs to my first original article in segmentfault. I hope it’s a good start. Let’s refuel together!

The copyright of this article belongs to the author and segmentfault. You are welcome to reprint it. However, without the consent of the author, you must keep this statement and give the original link in the obvious position on the page of the article. Otherwise, you reserve the right to pursue legal liability.