var a = 1;
var b = {
a : 2,
c : function () {
console.log(this.a);
}
};
b.c(); // logs 2
(b.c)(); // logs 2
(0, b.c)(); // logs 1
第一个是可以理解的,因为“this”指向对象“b”。但是为什么第二个记录相同的结果?我认为“this”应该指向全局执行上下文。第三个,似乎逗号运算符会影响执行上下文。
var a = 1;
var b = {
a : 2,
c : function () {
console.log(this.a);
}
};
b.c(); // logs 2
(b.c)(); // logs 2
(0, b.c)(); // logs 1
第一个是可以理解的,因为“this”指向对象“b”。但是为什么第二个记录相同的结果?我认为“this”应该指向全局执行上下文。第三个,似乎逗号运算符会影响执行上下文。
你真的有一个很好的角落案例!我的看法:
b
作为执行上下文。this
为全局对象,但实际上它保持链接。可能只是这样“随意”的语言用户不会惊慌失措。,
运算符),this
值就会丢失。这是因为b.c
是Property Reference
(规范中的深兔子洞细节,这里,由 TJCrowder 提供)。因此,您实际上是在传递函数本身,不再绑定到声明对象。因此,当您调用它时,它将this
作为全局对象传入。这样看:(object.function)()
被简单化为object.function()
,因为封闭的括号是完全可选的;(0, object.function)()
被解析为(expression yielding a function)()
将失去对 的object
绑定this
,因为函数已经解除绑定。
真的很好的例子!
请参阅Indirect eval call,其中提供了有关它的更多详细信息。
( 0 , b.c ) ( )
|____| |_____| |_____|
Literal Operator Identifier
|_________________________|
Expression
|______________________________|
PrimaryExpression
|______________________________| |________|
MemberExpression Arguments
|________________________________________________|
CallExpression
我们可以用逗号时尚间接调用b.c
,这将迫使它在执行global context
,valuea
是1
在global context
。
结果(b.c = b.c)()
也是1
> (b.c = b.c)()
1
就 ECMAScript 而言,这是因为 - 逗号运算符(
(0, b.c)
示例中)和=
运算符((b.c = b.c)
示例中)都对其操作数执行 GetValue。
其他间接调用格式如下
> (b.c, b.c)()
1
> (1? b.c: 0)()
1
> (__ = b.c)()
1