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
- Create an empty object
- Point the constructor’s this to the object
- Assign constructor properties to this object
- 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