【发布时间】:2020-08-30 02:11:05
【问题描述】:
我试图理解箭头函数中“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”。到这里为止一切都很好。然后我决定直接将 obj1.method 复制到其中,而不是定义 obj2.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 中获取 'this' 的值,即 obj1。
我做错了什么?
【问题讨论】:
-
箭头函数中的
this绑定到外部作用域的this。如果您在对象的方法内定义箭头函数,则外部范围this就是您调用该方法时的样子。 -
this的值绑定到定义箭头函数时的执行上下文。在您的示例中,.method()的调用定义了this的内容。obj1.method()->obj1,obj2.method()->obj2- 只是“正常”this规则 -> How does the “this” keyword work? -
@Teemu 但是词法作用域不是静态的(如answer 中所述)?如果作用域取决于函数的调用方式,那不是动态作用域吗?
-
什么是静态的?在这种情况下,static 表示作用域与其父作用域相同——在第一种情况下,父作用域是 obj1,在第一种情况下是 obj2第二种情况。
-
@muka.gergely 在词法作用域中,作用域是在编译时根据代码的词法结构确定的。正如您所说的那样,父范围在运行时正在发生变化。由于父作用域在运行时发生变化,因此“this”的作用域也在运行时发生变化。那为什么我们称之为词法作用域呢?
标签: javascript this arrow-functions