The arrow function is a new function type in ES6. Unlike normal functions, arrow functions have no this pointer themselves and must be determined by searching the scope. If the arrow function is contained by a non-arrow function, this is bound to the this of the nearest non-arrow function

  1. In non-strict mode, this refers to window
  2. In strict mode, this points to undefined in functions, but this points to window globally
  3. Using let, const variables does not bind to the window

I. Ordinary functions

For normal functions, this binds the window by default, and the function can access the global variables under the window

var c=1
function bar() { 
  var c = 11; 
  console.log(c); 
  console.log(this.c); 
  function inner() { 
    console.log(c); 
    console.log(this.c)
  };  
  inner(); 
}

bar()   // 11, 1, 11, 1
Copy the code
let d = 1
function bak() { 
  let d = 11; 
  console.log(d); 
  console.log(this.d);  
  function innerh() { 
    console.log(d); 
    console.log(this.d) 
  }; 
  innerh();

}

bak()   // 11, undefined, 11, undefined
Copy the code
  1. Variables defined by let and const are not bound to the window
  2. No matter how many layers the function has, as long as it is not an arrow function, the default bound this is always window
  1. If an object calls a function, the function’s this is implicitly bound to the object. This always refers to the nearest object before the function is called, because there may be nested child objects, in which case the function refers to the object that last called it.
function foo() {
    console.log(this.name);
}
var obj1 = {
    name: "obj1",
    foo: foo
};
var obj2 = {
    name: "obj2",
    obj1: obj1
};
obj2.obj1.foo();   // obj1
Copy the code

Note: The original binding object is lost when a function is assigned to a variable. The binding object is also lost when a function is passed as an argument

function foo () { console.log(this.a) } var obj = { a: 1, foo }; var a = 2; var foo2 = obj.foo; obj.foo(); // 1 this pointer in foo() points to the object obj foo2(); // 2 When foo() is assigned to another variable, foo's bound obj object is lost, so it points to window by defaultCopy the code
  1. The this point of a normal function is to force changes through call, apply, bind, and so on
function foo () { console.log(this.a) } var obj = { a: 1 }; var a = 11; foo(); // 11 This points to window foo.call(obj); // 1 this forcibly points to the obj object foo.apply(obj); // 1 foo.bind(obj) // does not execute, just creates a function without calling foo.bind(obj)(); // 1 to executeCopy the code
  1. The new binding constructs a new object and binds the new object to this in the calling function
function Person (name) { this.name = name; this.foo1 = function () { console.log(this.name); }; this.foo2 = function () { return function () { console.log(this.name); } } } var name = 'window'; var person1 = new Person('object'); Person1 // Person {name: "object", foo1: ƒ, foo2: ƒ} person1.foo1() // Object person1.foo2()() // Window pointer points to windowCopy the code

Arrow function

If the arrow function is contained by a non-arrow function, then this is bound to the nearest non-arrow function’s this; otherwise, this is undefined

var name = 'window'; function Person (name) { this.name = name this.foo1 = function () { console.log(this.name); } this.foo2 = () => { console.log(this.name); } } var person2 = { name: 'person2', foo2: () => { console.log(this.name) } } var person1 = new Person('person1'); person1.foo1(); //person1 person1.foo2(); //person1 because after new Person, person1's this points to Person person2.foo2(); // Window does not use the new operator because the arrow function this looks out to find the windowCopy the code

The arrow function this cannot be changed directly by bind, call, or apply, but can be changed indirectly by changing the direction of this in the scope

var name = 'window'; var obj1 = { name: 'obj1', foo1: function () { console.log(this.name); return () => { console.log(this.name); } }, foo2: () => { console.log(this.name); return function () { console.log(this.name); } } } var obj2 = { name: 'obj2', } obj1.foo1.call(obj2)(); Foo1 ().call(obj2); //obj2 obj2-call changes the this direction of foo1. //obj1 obj1-call cannot change the arrow function this to obj1.foo2.call(obj2)(); //window window-call does not apply to arrow functions obj1.foo2().call(obj2); // The window obj2-foo2 arrow function is a normal function inside, so it can change the this pointerCopy the code

Conclusion:

  1. This inside a function is determined by the outer scope and refers to this at the time the function is defined, not when it is executed
  2. The created object is a normal function. The default scope is Window, and this points to window if there is an arrow function attribute in it
  3. The constructor creates an object whose scope can be understood as the constructor, and whose this refers to the newly created object, so this refers to the object
  4. The arrow function this cannot be changed directly by bind, call, or apply, but can be changed indirectly by changing the direction of this in the scope