define

This is a binding to the current execution environment. Each function’s this is bound at call time, depending on where the function is called (i.e. how the function is called).

The position

Call location is the concept of call location and call stack in the previous call to the currently executing function

function baz() {
    // The current stack is: baz
    // Therefore the current call location is global scope
    
    console.log('baz')
    console.log(this)
    bar()   // <== bar call location
}

function bar() {
    // The current stack is: baz ==> bar
    // So the current call location is in baz
    
    console.log('bar')
    console.log(this)
    foo()   // <== foo's call location
}

function foo() {
    // The current stack is baz ==> bar ==> foo
    // So the current call location is in bar
    
    console.log('foo')
    console.log(this)
}
baz()   // <== baz call location
Copy the code

Now, if you run the code, you’ll see that the “this” printed out is the binding global environment. Why is that? Now, the concept of binding rules

Binding rules

  • The default binding

function foo() {
    console.log(this.a)
}
var a = 2
foo()   / / 2
Copy the code

As shown in the code above, foo is called from the global environment, so foo’s this is bound to the global environment, so the printed value is 2. In the code, Foo calls directly with an undecorated function reference, so only the default binding can be used. Special case: The default binding cannot be used in strict mode

function foo() {
    'use strict'
    console.log(this.a)
}
var a = 2
foo()   // typeError: this is undefined
Copy the code
  • Implicit binding

When a function reference has a context object, the function reference’s this is bound to that context object, which is implicitly bound demo

function foo() {
    console.log(this.a)
}
var a = 1
var obj = {
    a: 2.foo: foo
}
obj.foo()   / / 2
Copy the code

When the function foo is called, this in the function is bound to Obj, and only the last layer in the object property reference chain affects the location of the call

function foo() {
    console.log(this.a)
}
var obj = {
    a: 2.foo: foo
}
var obj1 = {
    a: 3.obj: obj
}
obj1.obj.foo()    //  2
Copy the code

As the code above shows in the obj1.obj.foo() call chain, this in foo is bound to its previous caller, obj. Implicit loss:

function foo() {
    console.log(this.a)
}
var obj = {
    a: 2.foo: foo
}
var bar = obj.foo
var a = 'global'
bar()   // global
Copy the code

Although bar is assigned by obj, it actually only refers to foo to bar, so bar is also essentially foo, so this is printed as a global this

  • According to the binding

Call, apply, and bind are display bindings, and this cannot change call after binding

function foo() {
    console.log(this.a)
}
var obj = {
    a: 12
}
var a = 24
foo.call(obj)   // 12, force this directly to obj by calling call
Copy the code

apply

function foo() {
    console.log(this.a)
}
var obj = {
    a: 12
}
var a = 24
foo.apply(obj)   // 12, force this directly to obj by calling apply
Copy the code

bind

function foo() {
    console.log(this.a)
}
var obj = {
    a: 12
}
const bar = foo.bind(obj)   // Unlike call and apply, bind returns a function that binds this
bar()   / / 12.
Copy the code
  • The new binding

What happens when you produce an instance with new

  1. Create an empty object
  2. Point the constructor’s this to the object
  3. Assign constructor properties to this object
  4. Returns the object
function foo(a) {
    this.a = a
}
const bar = new foo(2)
console.log(bar.a)   / / 2
Copy the code

priority

New Bind > Show Bind (Call,apply, Bind) > Implicit Bind > Default BindCopy the code

Bind the exception

  • Pass null or undefined as this binding object to call,apply, and bind. These values will be ignored when called, and the default binding rules will be applied.
function foo(a) {
    this.a = a
}
var a = 2
foo.call(undefind)  // 2
Copy the code

This lexical

Arrow functions: The this of arrow functions is determined by the outer layer. Default binding, implicit binding, display binding, and new binding are invalid

Function foo() {return () => {// The arrow function this is derived from foo this console.log(this.a)}} var obj1 = {a: 12} var obj2 = {a: 24} const bar = foo.call(obj1) // Bind returns a function called bar.call(obj2) //Copy the code

The arrow function created inside Foo captures foo’s this at the time of the call. Since Foo’s this is bound to obj1, the arrow function inside Foo, which was later assigned to bar’s this, is also bound to obj1 and cannot be changed, so it prints 12

The next chapter introduces the differences and implementation of Call,apply, and bind