问题
I'm asking because I've read similar (but not equal) questions about this issue.
As far as I understand, I get why this code would NOT work:
let myObj = {
name: 'inner text',
myFunction: () => {
console.log("before text " + this.name + " after text");
}
}
myObj.myFunction();
Reason: the context where the arrow function is created (myObj
) belongs to the global scope (which is window
or undefined
depending on strict mode and so on).
I get that. But in the case of nested object literals, shouldn't be the outer object literal the inherited context for the arrow function like following example?
let outer = {
name: 'outer',
obj: {
name: 'inner',
myFunction: () => {
console.log("before text " + this.name + " after text");
}
}
}
outer.obj.myFunction();
I would expect that this
refers to the context of outer
, which is the object literal where obj
is nested.
This is not the case and the reason I don't understand properly this inherited lexical scope.
Could someone throw some light about why is that happening?
回答1:
But in the case of nested object literals, shouldn't be the outer object literal the inherited context for the arrow function like following example?
No.
An arrow function copies the current value of this
;
var object = {
a: this,
b: {
a: this,
b: {
a: this
}
}
}
It doesn't matter how many levels you nest it, the value of this
doesn't change.
Since every level of the object literal appears in the same function, they all get the same this
value.
回答2:
There are many ways to accomplish what you want. The most compact could be to use a getter like follows:
let outer = {
name: 'outer',
obj: {
name: 'inner',
get myFunction() {
console.log("before text " + this.name + " after text");
return (this.name);
}
}
}
outer.obj.myFunction;
Inside a getter/setter your context is guaranteed to be the object instance (the most nested) (remember that each inner object is an 'independent' instance of Object, and getters/setters will belong to the nearest instance).
The problem with your code is that your arrow function is preserving the execution context at the time of creating the object.
Another way to achieve the intended behaviour would be to save a manually bound method as follows:
let outer = {
name: 'outer',
obj: {
name: 'inner'
}
}
outer.obj.myFunction = (function () {console.log("before text " + this.name + " after text");}).bind(outer.obj);
outer.obj.myFunction();
来源:https://stackoverflow.com/questions/57769860/lexical-context-of-this-in-nested-object-literals