对象方法 (Javascript) 内的词法范围绑定机制是什么?
What is the mechanism for lexical scope binding inside object methods (Javascript)?
我在理解箭头函数和词法范围时遇到了严重的大脑冻结:前段时间我通读了 Kyle Simpson 的所有“你不了解 JS”,我认为我很好地理解了范围和上下文.但我只是不理解箭头函数词法作用域如何应用于对象——我一直在 React 中使用 classes,而且箭头函数绑定到的 this
总是很清楚是 class.
例如,在这个例子中(来自https://medium.com/tfogo/advantages-and-pitfalls-of-arrow-functions-a16f0835799e)
let obj = {
myVar: 'foo',
myFunc: function() {
console.log(this.myVar)
setTimeout(() => {
console.log(this.myVar)
}, 1000)
}
}
箭头函数应该正确绑定 this
,避免执行 bind
。但这是来自词法范围?凭什么?因为下一个作用域是函数 myFunc
的作用域,而这个函数的词法父作用域是 obj
?
但是后来他们给出了这个例子
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
}
}
obj.myFunc() // undefined
this
的正确绑定不会发生。这是因为箭头函数周围没有函数,所以下一个词法范围是全局上下文吗?
总结一下:这里的 'lexical scope' 是否只是函数定义的相同词法作用域,而带箭头函数的 this
是否只是寻找下一个包含函数?
我向你保证我不久前就理解了这一点(或者我认为我理解了),但是 'use it or lose it',我猜 --
But this is from lexical scope? In what sense?
从某种意义上说,它与 this
在定义箭头函数的函数内部具有相同的值。
两者 console.log(this.myVar)
使用相同的 this
Because the next scope is that of the function myFunc and this function's lexical parent scope is obj?
myFunc
的父作用域无关紧要。它不是箭头函数。它从调用它的地方获取它的 this
值。
where correct binding of this does not happen.
this
与父函数相同。对象文字对其没有影响。
如果我们添加另一个 console.log,那么这两个(再次)引用相同的值。
console.log(this.myVar)
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
}
}
首先记住箭头函数的定义
箭头函数没有自己的this;使用封闭执行上下文的 this 值 (mozilla)
let obj = {
myVar: 'foo',
myFunc: function() {
console.log(this.myVar)
setTimeout(() => {
console.log(this.myVar)
}, 1000)
}
}
obj.myFunc();
The arrow function should bind this correctly, obviating doing a bind.
But this is from lexical scope? In what sense? Because the next scope
is that of the function myFunc and this function's lexical parent
scope is obj?
此处 setTimeout
回调的封闭函数是对象本身的一个方法,因此它将继承当前实例,如您所说。
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
}
}
obj.myFunc() // undefined
where correct binding of this does not happen. Is this because there
is no function surrounding the arrow function, and so the next lexical
scope is the global context?
在第二种情况下,在实例上声明的方法使用箭头函数,因此 this
将从封闭函数继承,但由于没有函数包装,您的对象将是 Window
箭头函数与所有其他函数具有相同的词法范围规则,但涉及 this
时除外。当你定义一个箭头函数时,它会在定义时捕获 this
现在的内容,并永远使用它。箭头函数中可用的任何值作为 thisin the lexical context of the arrow function's definition is the permanent value of
this`。
一种思考方式:如果我结束这个箭头函数定义,并且在定义之外立即使用 this
,那么 this
值会是多少?
在你的第二种情况下,再考虑一个 属性:
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
},
myOtherVar: this.myVar
}
我们肯定会将 myOtherVar
排除为 undefined
,因为当您构建此对象时,this
是 window
,它没有 myVar
属性。箭头函数也一样:它永久采用 window
的 this
,所以 this.myVar
是未定义的。
我在理解箭头函数和词法范围时遇到了严重的大脑冻结:前段时间我通读了 Kyle Simpson 的所有“你不了解 JS”,我认为我很好地理解了范围和上下文.但我只是不理解箭头函数词法作用域如何应用于对象——我一直在 React 中使用 classes,而且箭头函数绑定到的 this
总是很清楚是 class.
例如,在这个例子中(来自https://medium.com/tfogo/advantages-and-pitfalls-of-arrow-functions-a16f0835799e)
let obj = {
myVar: 'foo',
myFunc: function() {
console.log(this.myVar)
setTimeout(() => {
console.log(this.myVar)
}, 1000)
}
}
箭头函数应该正确绑定 this
,避免执行 bind
。但这是来自词法范围?凭什么?因为下一个作用域是函数 myFunc
的作用域,而这个函数的词法父作用域是 obj
?
但是后来他们给出了这个例子
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
}
}
obj.myFunc() // undefined
this
的正确绑定不会发生。这是因为箭头函数周围没有函数,所以下一个词法范围是全局上下文吗?
总结一下:这里的 'lexical scope' 是否只是函数定义的相同词法作用域,而带箭头函数的 this
是否只是寻找下一个包含函数?
我向你保证我不久前就理解了这一点(或者我认为我理解了),但是 'use it or lose it',我猜 --
But this is from lexical scope? In what sense?
从某种意义上说,它与 this
在定义箭头函数的函数内部具有相同的值。
两者 console.log(this.myVar)
使用相同的 this
Because the next scope is that of the function myFunc and this function's lexical parent scope is obj?
myFunc
的父作用域无关紧要。它不是箭头函数。它从调用它的地方获取它的 this
值。
where correct binding of this does not happen.
this
与父函数相同。对象文字对其没有影响。
如果我们添加另一个 console.log,那么这两个(再次)引用相同的值。
console.log(this.myVar)
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
}
}
首先记住箭头函数的定义
箭头函数没有自己的this;使用封闭执行上下文的 this 值 (mozilla)
let obj = {
myVar: 'foo',
myFunc: function() {
console.log(this.myVar)
setTimeout(() => {
console.log(this.myVar)
}, 1000)
}
}
obj.myFunc();
The arrow function should bind this correctly, obviating doing a bind. But this is from lexical scope? In what sense? Because the next scope is that of the function myFunc and this function's lexical parent scope is obj?
此处 setTimeout
回调的封闭函数是对象本身的一个方法,因此它将继承当前实例,如您所说。
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
}
}
obj.myFunc() // undefined
where correct binding of this does not happen. Is this because there is no function surrounding the arrow function, and so the next lexical scope is the global context?
在第二种情况下,在实例上声明的方法使用箭头函数,因此 this
将从封闭函数继承,但由于没有函数包装,您的对象将是 Window
箭头函数与所有其他函数具有相同的词法范围规则,但涉及 this
时除外。当你定义一个箭头函数时,它会在定义时捕获 this
现在的内容,并永远使用它。箭头函数中可用的任何值作为 thisin the lexical context of the arrow function's definition is the permanent value of
this`。
一种思考方式:如果我结束这个箭头函数定义,并且在定义之外立即使用 this
,那么 this
值会是多少?
在你的第二种情况下,再考虑一个 属性:
let obj = {
myVar: 'foo',
myFunc: () => {
console.log(this.myVar)
},
myOtherVar: this.myVar
}
我们肯定会将 myOtherVar
排除为 undefined
,因为当您构建此对象时,this
是 window
,它没有 myVar
属性。箭头函数也一样:它永久采用 window
的 this
,所以 this.myVar
是未定义的。