The arrow function this points to what was decided at definition time.
For this conclusion, in fact, to discuss the case.
- When the arrow function is used in the class definition method, it is determined at the time of its definition.
class Temp {
constructor() {
this.name = 'tariz';
}
getNameArrow = () = > {
console.log(this.name);
}
getName() {
console.log(this.name);
};
};
Copy the code
After the above code is converted by Babel
function _defineProperty(obj, key, value) {
if (key in obj) {
Object.defineProperty(obj, key, {
value: value,
enumerable: true.configurable: true.writable: true
});
} else {
obj[key] = value;
}
return obj;
}
class Temp {
constructor() {
_defineProperty(this."getNameArrow".() = > {
console.log(this.name);
});
this.name = "tariz";
}
getName() {
console.log(this.name); }}Copy the code
We’ll notice that when we use the arrow function to define a class method, the current method is bound to this. If we don’t call, bind, or apply to change this, this will always refer to an instance of the class.
- If you use arrow functions other than 1, and the arrow function’s this points to this depending on the execution context at the top of the definition (which may not be clear enough), let’s look directly at the code below.
const obj = {
name: 'tariz'.getName: () = > {
console.log(this.name); }};console.log(obj.getName()); // undefined
Copy the code
After Babel converts
var _this = this;
var obj = {
name: "tariz".getName: function getName() {
console.log(_this.name); }};Copy the code
The output value of the above code is undefined, which is not surprising, and I will explain it through chrome debugging.
The upper execution context of getName refers to the anonymous function at the beginning of the call (this is window), so this of getName refers to window, window does not have this attribute, so undefined.
If you are familiar with webPack packaging, there is a commonJS specification that implements each module as an anonymous function. If you are familiar with webPack packaging, each module is an anonymous function. Module. Exports, module. Require, module.
Let’s take this a step further with an example.
const obj = {
name: 'tariz'.getName() {
const showMyName = () = > {
console.log(this.name); }; showMyName(); }};const showMyNameWrapper = obj.getName;
obj.getName(); // tariz
showMyNameWrapper(); // undefined
Copy the code
In this example, the reference to this in the showMyName function depends on the execution context of the getName function, but the execution context of the getName function is unstable and dynamically determined during its execution.
In obj.getName(), this is obj in the context of the getName function execution, so the result printed in showMyName is tariz.
In showMyNameWrapper, the value of this around the execution of getName is window because the current getName is called globally and therefore undefined.
The arrow function’s this points to this depending on the execution context at the previous level
function Parent(s) {
s();
};
const obj = {
name: 'egg'.getName: function () {
new Parent(() = > { console.log('parent'.this.name) });
setTimeout(() = > { console.log('time:'.this.name) });
console.log(this.name);
const add = () = > { console.log(this.name) }; add(); }}; obj.getName();// parent egg
// egg
// egg
// time: egg
Copy the code
Babel compiles arrow functions:
function Parent(s) {
s();
}
var obj = {
name: "egg".getName: function getName() {
var _this = this;
new Parent(function () {
console.log("parent", _this.name);
});
setTimeout(function () {
console.log("time:", _this.name);
});
console.log(this.name);
var add = function add() {
console.log(_this.name); }; add(); }}; obj.getName();// This is already identified as this in the execution context of getName
Copy the code
The above code is more complex than the previous example and is analyzed through Chrome debugging.
When the Parent instance is created and the arrow function is executed, we find that the current function call stack is 4, among which the anonymous function pointed to by the red arrow is the current arrow function. Although the execution context of the previous layer is Parent, the arrow function is executed after its definition has determined that this points to the above guess. All this still refers to this of the getName execution context, which is obj.
Similarly, setTimeout performs a similar transformation. So this also executes the getName execution context of this, this process is not repeated explanation, if you are interested in debugging.