逗号运算符是否会影响Javascript中的执行上下文?

Ziq*_*iqi 28 javascript 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
Run Code Online (Sandbox Code Playgroud)

第一个是可以理解的,因为"this"指的是Object"b".但为什么第二个会记录相同的结果呢?我认为"this"应该指向全局执行上下文.第三个,似乎逗号运算符影响执行上下文.

A. *_*esa 18

你真的有一个漂亮的角落案件!我接受它:

  • 第一个是直截了当的.只是一个标准的电话.'.' 运算符允许您将函数设置b作为执行上下文调用.
  • 第二个是完全相同的事情:parens完全是可选的,解释器将其中的表达式视为绑定函数调用.实际上我并没有想到这一点:我认为解释器将重置this为全局对象,但实际上它保持链接.可能只是如此"随意"的语言用户不会惊慌失措.
  • 第三个是更标准的(至少对于那些生活在JavaScript中的人来说):只要你的函数在表达式中传递(在这种情况下由,运算符),this就会丢失绑定到执行上下文的值.所以,你实际上是在传递函数本身,不再与声明对象绑定.因此,当您调用它时,它将b.c作为全局对象传入.

这样看:Property Reference简单地进入this,因为封闭的parens是完全可选的; (object.function)()被解析为object.function()将失去(0, object.function)()绑定(expression yielding a function)(),因为函数已经解除绑定.

真的很好的例子!

  • 好的更新,尽管 *“只要你的函数在表达式中传递(在这种情况下是由 , 运算符),绑定到执行上下文的 this 值就会丢失”* 仍然不正确:我们没有使用 `this` ,我们正在使用`b`,并且最终没有使用对象引用的机制是因为属性引用没有直接用于进行调用。[§12.3.4.1](http://www.ecma-international.org/ecma-262/6.0/index.html#sec-function-calls-runtime-semantics-evaluation)中的详细信息。 (2认同)

zan*_*ngw 15

请参阅间接评估调用,其中提供了有关它的更多详细信息.

 (     0        ,          b.c   )        (  )
     |____|   |_____|    |_____|
     Literal  Operator   Identifier

     |_________________________|
     Expression

  |______________________________|
  PrimaryExpression

  |______________________________|        |________|
  MemberExpression                        Arguments

  |________________________________________________|

  CallExpression
Run Code Online (Sandbox Code Playgroud)

我们可以使用逗号运算符来形成一个间接调用b.c,它将强制它执行,其中global context的值a1global context.

结果(b.c = b.c)()也是1

> (b.c = b.c)()
  1
Run Code Online (Sandbox Code Playgroud)

就ECMAScript而言,这是因为 - 逗号运算符(在(0, b.c)示例中)和=运算符(在(b.c = b.c)示例中)都在其操作数上执行GetValue.

其他间接呼叫格式如下

> (b.c, b.c)()
  1 
> (1? b.c: 0)()
  1
> (__ = b.c)()
  1
Run Code Online (Sandbox Code Playgroud)