我试图理解箭头函数中'this'的词法范围。我尝试了以下代码
const obj1 = {
name: "obj1name",
method: function(){
return () => {return this.name};
}
};
const arrowFunc1 = obj1.method();
console.log(arrowFunc1());
const obj2 = {
name: "obj2name",
method: function(){
return obj1.method();
}
};
const arrowFunc2 = obj2.method();
console.log(arrowFunc2());
这就得到了输出-----------------------------------------------。
obj1name
obj1name
正如预期的那样,箭头函数内的'this'在词法上被限定为obj1,因此无论我们如何调用它,它都会打印出'obj1name'。直到这里,一切都很好。然后我决定不定义obj2.method,而是直接将obj1.method复制到其中----------。
const obj1 = {
name: "obj1name",
method: function(){
return () => {return this.name};
}
};
const arrowFunc1 = obj1.method();
console.log(arrowFunc1());
const obj2 = {
name: "obj2name",
method: obj1.method
};
const arrowFunc2 = obj2.method();
console.log(arrowFunc2());
这就得到了输出-----------------------------------------------。
obj1name
obj2name
我不明白为什么它会打印'obj2name'。
我的理解是,箭头函数是在obj1.method中定义的,所以它的词法范围在其中。因此,它应该从obj1.method即obj1中获取'this'的值。
我到底错在哪里?
它的词法范围是:你在obj1中定义了一个函数(箭头),但在obj2中调用了它--obj2的词法范围是obj2--所以你在那里调用的方法按理说可以工作。
代码段中的 console.logs 显示了这个问题。
const obj1 = {
name: "obj1name",
method: function(){
return () => {return this.name};
}
};
const arrowFunc1 = obj1.method();
console.log(arrowFunc1());
const obj2 = {
name: "obj2name",
method: obj1.method
};
const arrowFunc2 = obj2.method();
console.log(arrowFunc2());
// these console.logs show your problem:
console.log('obj1:', obj1)
console.log('obj2:', obj2)
在你的例子中, function()
为 this
- 并且 function()
是在 obj2
.
也许这个片段可以帮助你理解更多。
// extracted the function, but left the "this"
// just calling the function in itself would throw an
// error, but inside an object (that has a name property)
// it works nicely
const fn = function() {
return () => {
return this.name
}
}
const obj1 = {
name: "obj1name",
method: fn
};
const arrowFunc1 = obj1.method();
console.log(arrowFunc1());
const obj2 = {
name: "obj2name",
method: fn
};
const arrowFunc2 = obj2.method();
console.log(arrowFunc2());
// these console.logs show your problem:
console.log('obj1:', obj1)
console.log('obj2:', obj2)
最后一个片段:
const obj1 = {
name: "obj1name",
method: function() {
return () => {
return this.name
};
}
};
const arrowFunc1 = obj1.method();
console.log(arrowFunc1());
// if you want to call with obj1, then it's not enough to add the
// function - you have to CALL (invoke) it
const obj2 = {
name: "obj2name",
method: obj1.method()
};
// see that there're no parantheses after obj2.method - its
// value is resolved when creating obj2 by INVOKING the function
const arrowFunc2 = obj2.method;
console.log(arrowFunc2());
// these console.logs show your problem:
console.log('obj1:', obj1)
console.log('obj2:', obj2)
这个:
const obj1 = {
name: "obj1name",
method: function(){
return () => {return this.name};
}
};
应该是这个
const obj1 = {
name: "obj1name",
method: () => {return this.name}
};
通过将箭头函数包装在一个常规函数中... ...作用域再次成为调用者的作用域.