preface
Recently was looking at you don’t know JavaScript, about this part of the binding mechanism of very good, very clear, as is the use of this part of our js quite a key, and it is also a frequency test of the interview, so to arrange an article to share this part of the content, believe see analysis of this article, you will learn, If you like, you can click Bozam/Follow and support it.
Swimming, fitness know about: blog, front-end accumulation of documents, public number, GitHub
Why use this:
function identify() {
console.log("Hello,I'm " + this.name);
}
let me = {
name: "Kyle"
};
let you = {
name: "Reader"
};
identify.call(me); // Hello,I'm Kyle
identify.call(you); // Hello,I'm Reader
Copy the code
This simple idea allows you to reuse the function identify across different objects without having to write a new function for each object.
This solves the following problems:
This provides a more elegant way to implicitly ‘pass’ a reference to an object, so the API can be designed to be cleaner and easier to reuse.
There are four binding rules for this:
Default binding:
Rule: In non-strict mode, the default binding this refers to a global object, and in strict mode this refers to undefined
function foo() { console.log(this.a); } var a = 2; foo(); // 2 function foo2() { "use strict"; // Strict mode this is bound to undefined console.log(this.a); } foo2(); // TypeError:a undefinedCopy the code
The default binding rules are as described above, with a subtle detail:
function foo() { console.log(this.a); // foo does not bind global objects by default} var a = 2; function foo2(){ "use strict"; foo(); } foo2();} foo2(); / / 2Copy the code
So: For the default binding, what determines the this binding object is whether the function body is in strict mode, pointing strictly to undefined and not strictly to the global object.
You don’t usually mix strict and non-strict patterns in your code, so this is a rare occurrence, so just be aware of it and avoid some wacky interview questions.
Implicit binding:
Rule: Does the function have a context object at the call location? If so, this is implicitly bound to the object.
function foo() { console.log(this.a); } var a = "Oops, global"; let obj2 = { a: 2, foo: foo }; let obj1 = { a: 22, obj2: obj2 }; obj2.foo(); // 2 this refers to the calling object obj1.obj2.foo(); // let bar = obj2.foo; // Let bar = obj2.foo; // bar is just a function whose alias is a reference to obj2.foo bar(); // "Oops, global" - points to globalCopy the code
Implicit binding loss:
Implicit binding loss problem: in fact, when a function is called, there is no context object, just a reference to the function, so implicit binding loss can occur.
The same problem occurs with the incoming callback function, which is more common and insidious, like this:
test(obj2.foo); // Pass a reference to a function, which is called without a context object.Copy the code
Explicit binding:
As we saw above, there is no way to get the desired binding using implicit binding alone, but fortunately we can also force a function call on an object to bind this to that object.
Rule: We can bind this in functions to specified objects using apply, call, and bind.
function foo() { console.log(this.a); } let obj = { a: 2 }; foo.call(obj); / / 2Copy the code
Passed in is not an object:
If you pass in a primitive value (string, Boolean, number) as a binding object to this, the primitive value is converted to its object form.
If you pass null or undefined as a binding object for this to call/apply/bind, these values will be ignored and the default binding rules will apply.
The new binding:
In JS, there is no such thing as a ‘constructor’, only a ‘constructor call’ to a function.
What do you do when you are new?
- Create a brand new object.
- The new object will be connected by [[Prototype]].
- This new object is bound to the function call’s this.
- If the function returns no other object, the function call in the new expression automatically returns the new object.
Rule: When using a construct call, this is automatically bound to objects created during new.
function foo(a) { this.a = a; } let bar = new foo(2); console.log(bar.a); / / 2Copy the code
This Specifies the priority of the four binding rules
If more than one rule is applied at an invocation location, how do I determine which rule is in effect?
obj.foo.call(obj2); // This points to obj2. Explicit binding has higher priority than implicit binding. new obj.foo(); // thsi points to new. The new binding has a higher priority than the implicit binding.Copy the code
Explicit binding and new binding cannot be directly compared (error). The default binding is the bottom binding after no other rules have been applied, so it has the lowest priority.
Explicit binding > Implicit binding > Default binding
New Binding > Implicit binding > Default binding
The arrow function’s this pointer does not use any of these four rules:
function foo() { return () => { console.log(this.a); }; } let obj1 = { a: 2 }; let obj2 = { a: 22 }; let bar = foo.call(obj1); // foo this points to obj1 bar.call(obj2); // Output 2 executes the arrow function here and tries to bind this to obj2Copy the code
From the above, it can be concluded that the arrow function this rule:
- The this in the arrow function inherits the this pointer of the first function outside it that is not the arrow function.
- The arrow function’s this, once context-bound, will not be changed by any code.
PS: The difference between the arrow function and the ordinary function, as well as the matters needing attention of the arrow function, does not apply to the scene, interested students can expand.
conclusion
After reading this, I believe you have already got the usage of this. Finally, I recommend “JavaScript you don’t know”. This book is really good and interesting.
Blog, front-end accumulation of documents, public account, GitHub, Wx :OBkoro1, email: [email protected]
The above 2018.6.30