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”指的是Object“b”。但为什么第二个会记录相同的结果呢?我认为“this”应该指向全局执行上下文。第三个,似乎逗号运算符影响执行上下文。
答案 0 :(得分:17)
你真的有一个漂亮的角落案例! 我接受了它:
b
作为执行上下文调用。this
重置为全局对象,但实际上它会保持链接。可能只是这样“随意”的语言用户不会惊慌失措。,
运算符传递){{1}绑定到执行上下文的值将丢失。因此,您实际上是在传递函数本身,而不再与声明对象绑定。因此,当您调用它时,this
将作为全局对象传入。这样看:this
被简化为(object.function)()
,因为封闭的parens是完全可选的; object.function()
被解析为(0, object.function)()
,它将失去(expression yielding a function)()
与object
的绑定,因为函数已经解除绑定。
非常好的例子!
答案 1 :(得分:15)
请参阅Indirect eval call,其中提供了有关它的更多详细信息。
( 0 , b.c ) ( )
|____| |_____| |_____|
Literal Operator Identifier
|_________________________|
Expression
|______________________________|
PrimaryExpression
|______________________________| |________|
MemberExpression Arguments
|________________________________________________|
CallExpression
我们可以使用逗号运算符来设置对b.c
的间接调用,这将强制它在global context
中执行,a
的值为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