隐藏 `this` - 词法名称解析
Shadowing `this` - lexical name resolution
编辑:我认为这不是重复的;它是一个隐藏参数,我想问一下与 this
相关的阴影和词法范围,阅读了 this SO Q/A re。阴影。
我认为名称 this
的含义可能会被动态解析(在范围界定方面),以解释为什么在我看来它没有被词法解析:
function foo() {return this;}
var a = {f: foo};
var b = {f: foo};
a.f() !== b.f();
a.f() !== foo();
a.f() !== window; //not strict mode
但后来我读到每个函数都默默地接收 this
作为附加参数。 (我意识到箭头函数是不同的。)
显然 helper()
没有像我们希望的那样工作:
ob = {
meth: function(){
var helper = function() {return this;};
return helper();
}
};
ob.meth(); //Window or undefined
据我所知,解释器不是通过查看封闭范围来解决 this
(结果是 ob
),而是用 [= 调用 helper()
12=] 设置为 undefined
(严格模式),作为参数静默传递。
那么周围作用域的 this
是否实际上是 shadowed,因此词法作用域实际上在起作用?
你是对的。除了箭头函数, this
永远不会在词法上解析。它总是指以下之一:
- 调用函数的对象,例如
valueOfThis.foo()
apply
或 call
的第一个参数,例如 foo.apply(valueOfThis, params)
或 foo.call(valueOfThis, ...)
。
- DOM 元素,在事件处理程序的情况下,例如
<button onclick="alert(this.tagName.toLowerCase());"/>
- 正在构造的对象,当函数作为构造函数时,如
Foo = function(){ ... }; new Foo()
- 绑定到函数的对象,如果函数是使用
bind
创建的,例如bar = function(){ ... this ...}; foo = bar.bind(valueOfThis); foo()
- 在getter/setter中,
this
指的是属性被访问或设置的对象,如valueOfThis.someProperty = 123
window
(通常)如果none以上情况,如foo()
@Bergi 在下面的评论中为所有这些提供了 great reference。
在 绑定函数 的情况下,被调用的函数实际上是一个不同于传递给 bind
方法的函数,因为 bind
方法创建一个新函数
So is the surrounding scope's this effectively being shadowed, hence lexical scoping is in fact in action?
是的,可以从那个角度来看。绑定到 helper
范围的 this
隐藏绑定到 meth
范围的那个。 (如果你使用了箭头函数,它就不会)。
不过,你还是要记住,this
不是一个普通的变量,而是一个特殊的关键字。它只绑定到函数范围,它不可写,它在草率模式下有奇怪的强制对象语义,而且它总是隐式绑定——正如你所说,一个隐藏参数。
除非您试图了解 this
如何在箭头函数(及其词法解析)中工作,否则与作用域和阴影的类比是毫无用处的。
编辑:我认为这不是重复的;它是一个隐藏参数,我想问一下与 this
相关的阴影和词法范围,阅读了 this SO Q/A re。阴影。
我认为名称 this
的含义可能会被动态解析(在范围界定方面),以解释为什么在我看来它没有被词法解析:
function foo() {return this;}
var a = {f: foo};
var b = {f: foo};
a.f() !== b.f();
a.f() !== foo();
a.f() !== window; //not strict mode
但后来我读到每个函数都默默地接收 this
作为附加参数。 (我意识到箭头函数是不同的。)
显然 helper()
没有像我们希望的那样工作:
ob = {
meth: function(){
var helper = function() {return this;};
return helper();
}
};
ob.meth(); //Window or undefined
据我所知,解释器不是通过查看封闭范围来解决 this
(结果是 ob
),而是用 [= 调用 helper()
12=] 设置为 undefined
(严格模式),作为参数静默传递。
那么周围作用域的 this
是否实际上是 shadowed,因此词法作用域实际上在起作用?
你是对的。除了箭头函数, this
永远不会在词法上解析。它总是指以下之一:
- 调用函数的对象,例如
valueOfThis.foo()
apply
或call
的第一个参数,例如foo.apply(valueOfThis, params)
或foo.call(valueOfThis, ...)
。- DOM 元素,在事件处理程序的情况下,例如
<button onclick="alert(this.tagName.toLowerCase());"/>
- 正在构造的对象,当函数作为构造函数时,如
Foo = function(){ ... }; new Foo()
- 绑定到函数的对象,如果函数是使用
bind
创建的,例如bar = function(){ ... this ...}; foo = bar.bind(valueOfThis); foo()
- 在getter/setter中,
this
指的是属性被访问或设置的对象,如valueOfThis.someProperty = 123
window
(通常)如果none以上情况,如foo()
@Bergi 在下面的评论中为所有这些提供了 great reference。
在 绑定函数 的情况下,被调用的函数实际上是一个不同于传递给 bind
方法的函数,因为 bind
方法创建一个新函数
So is the surrounding scope's this effectively being shadowed, hence lexical scoping is in fact in action?
是的,可以从那个角度来看。绑定到 helper
范围的 this
隐藏绑定到 meth
范围的那个。 (如果你使用了箭头函数,它就不会)。
不过,你还是要记住,this
不是一个普通的变量,而是一个特殊的关键字。它只绑定到函数范围,它不可写,它在草率模式下有奇怪的强制对象语义,而且它总是隐式绑定——正如你所说,一个隐藏参数。
除非您试图了解 this
如何在箭头函数(及其词法解析)中工作,否则与作用域和阴影的类比是毫无用处的。