1. What is this binding

  • Test in the browser that this points to window
  • In the global context, we can think of this as referring to the window

2. Several binding rules

  1. The default binding

    1. Normal function call: window
    2. Function call chain (one function calls another function) : window
    3. Pass the function as an argument to another function: window
  2. Implicit binding

    1. Calling a function from an object: this is bound to the object. If there are calls between objects, if obj2 has obj1, then obj2.obj1.foo() -> this points to obj1
    2. Implicit loss: Look at the final call location
     function foo(){
         console.log(this)}var obj1 = {
         name: "obj1".foo: foo
     }
    
     // Assign foo of obj1 to bar
     var bar = obj1.foo
     bar()
    Copy the code
  3. According to the binding

    1. Call, apply: Use call, apply to specify objects bound to this
    // Implement a bind function
    
    / / method
    function foo(){
        console.log(this)}var obj = {
        name: 'hzy'
    }
    
    function bind(func,obj){
        return function(){
            func.apply(obj,argument)
        }
    }
    
    var bar = bind(foo,obj)
    
    bar() // obj
    bar() // obj
    
    // function.prototype.bind
    function foo(){
        console.log(this)}var obj = {
        name: 'hzy'
    }
    
    var bar = foo.bind(obj)
    
    bar() // obj
    bar() // obj
    Copy the code
    1. Built-in function
      1. SetTimeout: Indicates the window by default
      2. Array forEach: the default is to point to the window, and the last parameter of forEach can specify the binding of this
      3. Div Click: We add the function this in the click event to specify the DOM element fetched
  4. The new binding

    1. Create a brand new object
    2. Perform Prototype concatenation on this object
    3. The new object will be bound to this of the function call (this does not complete the this binding).
    4. If the function returns no other object, the expression returns the new object
    5. Note: New cannot be used together with call and apply
  5. Binding priority

    1. New Bind -> Show Bind -> Implicit bind -> Default bind
  6. Outside of this rule

    1. Ignore display binding: null, Undefined -> window
    2. Indirect function reference: Creates a function indirect reference, using the default binding rules
function foo(){
    console.log(this)}var obj1  = {
    name: 'obj1'.foo: foo
}

var obj2 = {
    name: 'obj2'
}

obj1.foo() / / object obj1
(obj2.foo = obj1.foo)() // window
Copy the code
  1. ES6 arrow function
    1. Var _this = this;
    2. Using the arrow function, the arrow function’s this defaults to looking up

3. This topic

  1. Subject to a
var name = "window";
var person = {
  name: "person".sayName: function () {
    console.log(this.name); }};function sayName() {
  var sss = person.sayName;
  sss();
  person.sayName();
  (person.sayName)();  
  (b = person.sayName)();  
sayName();





function sayName() {
  var sss = person.sayName;
  // Independent function call, not associated with any object
  sss(); // window
  / / associated
  person.sayName(); // person
  (person.sayName)(); // person
  (b = person.sayName)(); // window
}
Copy the code
  1. Topic 2
var name = 'window'
var person1 = {
  name: 'person1'.foo1: function () {
    console.log(this.name)
  },
  foo2: () = > console.log(this.name),
  foo3: function () {
    return function () {
      console.log(this.name)
    }
  },
  foo4: function () {
    return () = > {
      console.log(this.name)
    }
  }
}

var person2 = { name: 'person2' }

person1.foo1();  // person1
person1.foo1.call(person2); // person2

person1.foo2(); // window
person1.foo2.call(person2); // window

person1.foo3()(); // window
person1.foo3.call(person2)(); // window
person1.foo3().call(person2); // person2

person1.foo4()(); // person1
person1.foo4.call(person2)(); // person2
person1.foo4().call(person2); // person1



// Implicit binding, must be person1
person1.foo1(); // person1
// a combination of implicit binding and display binding, display binding in effect, so person2
person1.foo1.call(person2); // person2

// foo2() is an arrow function and does not apply all rules
person1.foo2() // window
// Foo2 is still an arrow function and is not used to display binding rules
person1.foo2.call(person2) // window

// Get foo3, but the call location is global, so the default binding is window
person1.foo3()() // window
// foo3 shows binding to person2
// But the return function is still called globally, so it is still window
person1.foo3.call(person2)() // window
// Get the function returned by foo3 and bind it to person2 by display, so person2
person1.foo3().call(person2) // person2

// Foo4 () returns an arrow function
// The arrow function is executed in the upper scope, person1
person1.foo4()() // person1
// foo4() shows bindings to person2 and returns an arrow function
// The arrow function looks for the upper scope, person2
person1.foo4.call(person2)() // person2
// foo4 returns the arrow function, which only looks at the upper scope
person1.foo4().call(person2) // person1
Copy the code
  1. The title three
var name = 'window'
function Person (name) {
  this.name = name
  this.foo1 = function () {
    console.log(this.name)
  },
  this.foo2 = () = > console.log(this.name),
  this.foo3 = function () {
    return function () {
      console.log(this.name)
    }
  },
  this.foo4 = function () {
    return () = > {
      console.log(this.name)
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.foo1() // person1
person1.foo1.call(person2) // person2

person1.foo2() // person1
person1.foo2.call(person2) // person1

person1.foo3()() // window
person1.foo3.call(person2)() // window
person1.foo3().call(person2) // person2

person1.foo4()() // person1
person1.foo4.call(person2)() // person2
person1.foo4().call(person2) // person1





// Implicit binding
person1.foo1() // peron1
// Display binding priority over implicit binding
person1.foo1.call(person2) // person2

// foo is an arrow function that looks for this in the upper scope, so person1
person1.foo2() // person1
// foo is an arrow function. Using call does not affect this binding
person1.foo2.call(person2) // person1

// Call location is global direct call, so still window (default binding)
person1.foo3()() // window
// Finally get the function returned by foo3 and call it globally (default binding)
person1.foo3.call(person2)() // window
// Take the function returned by foo3 and bind it to person2 via call
person1.foo3().call(person2) // person2

// foo4 returns the arrow function, regardless of its binding, to find person1
person1.foo4()() // person1
// foo4 is bound to person2, and the arrow function is returned. When called, the upper bound person2 is found
person1.foo4.call(person2)() // person2
// Foo4 calls the returned arrow function, independent of the call call, to find the upper-level person1
person1.foo4().call(person2) // person1
Copy the code
  1. The title four
var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj'.foo1: function () {
      return function () {
        console.log(this.name)
      }
    },
    foo2: function () {
      return () = > {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo1()() // window
person1.obj.foo1.call(person2)() // window
person1.obj.foo1().call(person2) // person2

person1.obj.foo2()() // obj
person1.obj.foo2.call(person2)() // person2
person1.obj.foo2().call(person2) // obj







// obj.foo1() returns a function
// This function executes directly under global effects (default binding)
person1.obj.foo1()() // window
// Finally get a return function (although there is an extra call binding)
// This function executes directly under global effects (default binding)
person1.obj.foo1.call(person2)() // window
person1.obj.foo1().call(person2) // person2

// Get the return value of foo2(), which is an arrow function
// The arrow function looks for this in the upper scope, which is obj
person1.obj.foo2()() // obj
// The return value of foo2() is still the arrow function, but bound to person2 when foo2 is executed
// The arrow function looks for this in the upper scope and finds person2
person1.obj.foo2.call(person2)() // person2
// the return value of foo2() is still the arrow function
// Arrow functions called by call do not bind this, so this in the upper scope is obj
person1.obj.foo2().call(person2) // obj
Copy the code

Coderwhy