Here’s a preview:

  • The global object’s this refers to the window object
  • The global function executes this to point to the window
  • This always refers to the object that last called it
  • The new keyword changes the this direction
  • Apply Call Bind can change this to point
  • The arrow function’s this is determined at definition time
  • The this of an anonymous function always points to the window

one

The global object’s this refers to the window object

  var a = 1000;
  var obj = {
      a: 1.b: this.a+1
  }
  console.log(obj.b);
Copy the code

The normal object obj does not have this; this refers to the window object. The code above prints 1001

two

The global function executes this to point to the window

  function fun(){
      console.log(this= = =window)       //true
  }
Copy the code

So:

  var name = "William";
  function test(){
      var name = "Lisi";
      let a = {
          name: this.name
      }
      console.log(a.name);
  }
  test();
Copy the code

Distinguish this from constructors. After test() is executed, William is printed

three

This always refers to the object that last called it

From juejin. Cn/post / 684490… This applies to calls to non-arrow functions. It is the same as the previous two sentences.

Example 1

  var a = 1000;
  function fun(){
      var obj = {
          a: 1.c: this.a + 2
      }
      return obj.c;
  }  
  console.log(fun());
Copy the code

The fun function is executed with this pointing to the window, so obj. C = 1002; The output of 1002

Case 2

  var name = "windowsName";
  function fn() {
      var name = 'Cherry';
      innerFunction();
      function innerFunction() {
          console.log(this.name);      
      }
  }
  fn()
Copy the code

The fn function is executed with this pointing to the window. The innerFunction does not have this.name inside it, but as the scope looks up, the innerFunction eventually accesses window.name

Example 3

  let obj = {
      name: "William".say: function(){
          console.log(this.name);
      }
  }
  obj.say();
Copy the code

See, “This always refers to the object that called it last.” When executed, the say function is called by obj, so it refers to obj, and this.name refers to obj.name.

four

The new keyword changes the this direction

  const a = 1000;
  function f1(a, b){
      this.a = a;
      this.b = b;
      console.log(this= = =window);
  }
  f1();                                  //true
  const f = new f1(1.2);                //false
  console.log(f.a);
Copy the code

So what does the new operator do?

  1. First, an empty object obj is created internally
  2. Point the new object’s __proto__ to the constructor’s Prototype object
  3. Assign the constructor’s scope to the new object (that is, this refers to the new object)
  4. Execute the code in the constructor (add attributes to this new object)
  5. Returns the result of the apply execution or returns an object
  // Simulate new code
  function create(fn, ... rest){
      const obj = Object.create(fn.prototype);
      const result = fn.apply(obj, rest);
      if(typeof result === "object") {return result;
      }else{
          returnobj; }}Copy the code

five

Apply Call Bind can change this to point

Specifically, change the this orientation of non-arrow functions.

  let obj = {
      name: "William".say: function(){
          console.log(this.name);
      }
  }
  obj.say();
  obj.say.apply({name: "Ben"})
Copy the code

six

The arrow function’s this is determined at definition time.

In fact, there are many other features of the arrow function, to summarize:

  • The arrow function’s this is determined at definition time
  • Arrow functions have no prototype property and are purer functions.
  • Arrow functions cannot use the new keyword.
  • Arrow functions have no arguments and can use… Rest solves the problem of variable parameter length
  • Apply Call Bind cannot modify this of the arrow function

By escaping the ES6 code with Babel, you can see that the arrow function’s this is converted when it is defined, so the arrow function’s this is defined when it is defined.

 window.color = "red";
  let color = "green";
  // var color = "black";
  let obj = {
    color: "blue"
  };
  let sayColor = () = > {
    return this.color;
  };
  console.log(sayColor.apply(obj));
Copy the code

SayColor is an arrow function, applay does not work, so the “this” in the function is not changed. The this in the arrow function is what this points to by definition. When we define sayColor, this refers to the global window. So this.color refers to window.color. Let const variables are not loaded onto the window. So let color does not change the window.color value.

seven

The this of an anonymous function always points to the window

An execution environment with no variables pointing to anonymous functions is global, so its this object usually points to window

What is an anonymous function that has no variable to point to? Such as:

setTimeout(function(){}, 100)

arr.forEach(function(){})

function(){ return function(){}}Copy the code

The functions inside have no variables pointing to them, and the execution environment of these functions is global, so their this object usually points to the window. In the following code, obj.getNameFunc refers to the following anonymous function, so this refers to obj in the obj.getNameFunc execution. The arrow function solves this problem.

 var name = "The window";
  var object = {
    name: 'My Object'.getNameFunc: function () {
      console.log(this);
      return function () {
          return this.name; }},getName: function () {
      return () = >{
        return this.name; }}}console.log(object.getNameFunc()());
  console.log(object.getName()());
Copy the code

console.log(object.getNameFunc()()); Execute “The window” console.log(object.getName()()); Execute the output “My Object”

Confusing topics (constantly updated)

Title 1:

  var name = "The Window";
  let obj = {
      name: "My Object".say: function(){
          console.log(this.name); }}; obj.say(); (obj.say)();const fn = obj.say;
  fn();
  (obj.say=obj.say)();
Copy the code

obj.say(); And (obj. Say) (); The effect is the same. Because obj. Say (); And (obj. Say) (); The definition of is the same. const fn = obj.say; This is an assignment statement, The value of The assignment expression is The function itself, so The value of this cannot be maintained, The result is “The Window” again, (obj.say=obj.say)(); The value of this cannot be maintained, so “The Window” is returned.

Topic 2:

var a = function(){
    this.b = 3;
}

var c = new a();
a.prototype.b = 9;
var b = 7;
a();
console.log(b);
console.log(c.b);
Copy the code

Function A is a global function, not a property of an object. So execute a(); This refers to the global window, and global B becomes 3. Execute the constructor new a(); C.b = 3; So it prints two 3’s

Title 3:

var a  = [1.2.3.4];
for (var i = 0; i< a.length; i ++ ) {
    setTimeout(() = > {
        console.log(a[i])
    }, i * 1000);
}
Copy the code

By the time the for loop completes, I has become 4, so a[4] is undefined

The last

If there is any mistake or not precise place, please give correction, thank you very much. If you like or have some inspiration, welcome to like, to the author is also a kind of encouragement.