This is the 8th day of my participation in Gwen Challenge
What on earth is this
When a function is called, an execution context is created, with the following lifecycle:
Create {generate variable object, establish scope chain, make sure this points to} —–> execute {variable assignment, function reference, execute other code} —–> execute and wait to be reclaimed
We need to clear up the misunderstanding that this refers neither to the function itself nor to the lexical scope of the function. This is a property of the execution context that points to the execution context object. This is a binding that only happens when the function is called, and what it points to depends entirely on where the function is called.
2. Binding rules
To figure out what this refers to, you need to find where the function is called. The call location is where the function is called during execution, not where it is declared. Such as:
function a(){
console.log(‘a’);
}
function b(){
console.log(‘b’)
a(); –> Call location
}
a(); –> Call location
1. Default binding
The default binding is also called a global binding.
In non-strict mode, when a function is executed, it is bound by default if it is called from an undecorated function reference.
When using the default binding, this points to a global object.
Here’s an example:
var a = 1;
function aa(){
The console. The log (enclosing a);
}
function bb(){
var a = 2;
console.log(this.a);
aa();
}
bb(); / / output 1,
2. Implicit binding (called as a property of an object)
When a function reference has a context object, the implicit binding rule binds this in the function call to that context object.
Here’s an example:
function aa(){
console.log(this.a);
}
var obj = {
a:2,
aa:aa
};
obj.aa(); / / 2
Because this is bound to obj when aa() is called, this.a is the same as obj.a.
It is important to note that only the previous or last level in the object attribute reference chain plays a role in the call location.
Implicit loss:
Implicitly bound functions may in some cases lose the bound object and use the default binding (non-strict mode).
Here’s an example:
function aa(fn){
console.log(this.a);
}
function doAA(fn){
fn(); <– call location
}
var obj = {
a:2,
aa:aa
}
var a = “global”;
doAA(obj.aa); // “global”
Parameter passing is essentially an implicit assignment. Fn is a reference to obj. Aa, but it refers to the function itself. So fn() does not have any modifier function calls in front of it, so the default binding is used.
This is especially noticeable when the callback function loses the this binding.
3. Use call to explicitly bind
If we want to force a function call on an object rather than include a function reference inside the object, we can use call or apply. Most functions can use these two methods.
The first argument to both methods is an object to be bound to this, and the second argument to be passed to the executing function. Here’s an example:
function aa{
console.log(this.a);
}
var obj = {
a:2
}
aa.call(obj);
Bind this to obj with aa.call().
4. The new binding
In javascript, constructors are simply functions that are called when the new operator is used. They don’t belong to a class, they’re just ordinary functions called by the new operator. When a function is called with new, the new object is bound to this of the function call. Here’s an example:
function aa(a){
this.a = a;
}
var bb = new aa(2);
console.log(bb.a); / / 2
When aa() is called with new, a new object is constructed and bound to this in the aa() call.
Priority
Now we know that there are these binding rules, but what if there are multiple rules for a particular invocation location, so we need to prioritize those rules.
The following priorities are in descending order:
1. The new binding.
2. Call, apply calls binding.
3. Binding is invoked by context, i.e. implicit binding.
4. Default binding: bind to undefined in strict mode, otherwise bind to global object.
4. Exceptional arrow functions
The arrow function is not defined by function, but by arrow. It does not use the four rules of this. It inherits the this binding of the outer function call. Here’s an example:
function aa(){
return (a) => {
console.log(this.a);
}
}
var obj_1 = {
a:1
}
var obj_2 = {
a:2
}
var ss = aa.call(obj_1) // 1
ss.call(obj_2) // 1
The aa() function this is bound to obj_1, so the arrow function is bound to obj_1.