Javascript:围绕逗号分隔表达式的圆括号

时间:2013-08-18 21:46:20

标签: javascript scope closures

在JS控制台上玩我遇到了一种奇怪的语法。我想知道是否有人可以告诉我更多......

试试这个:

>( function f(){console.log('i am f')} , (function x(){console.log('i am x')})() , y=2 , console.log('hello') )
i am x
hello
undefined
>f()
ReferenceError: f is not defined
>this.y
2

这将失败:

  

(var c = 2)       SyntaxError:意外的标记var

因此评估括号内的逗号分隔表达式,赋值碰巧是针对全局范围的,但命名函数声明引用仍然被困在内部就像一个闭包 更多... 将该行放在使用 new 调用的函数声明中:

function C(){
    ( function f(){console.log('i am f')} , (function x(){console.log('i am x')})() , y=2 , console.log('hello') )
}

然后实例化:

>var c=new C()
i am x
hello
undefined
>c.y
undefined
>this.y
2

发生完全相同,就像在全局范围内执行一样!

这种结构的用途/目的是什么?

还有一个:

>( function f(){console.log('i am f')} , f() )
ReferenceError: f is not defined

因此,命名函数既不能在括号内引用。

2 个答案:

答案 0 :(得分:6)

命名函数不是“被困在里面”,因为它们不是函数声明(使用function as a statement),它们实际上是函数表达式 (使用function as an operator)。这意味着它们的名称不会成为当前名称空间中对它们自己的引用。


某些关键字/标记只能用作语句,例如var,因此如果您尝试在解释器期望作为表达式的条件中使用它们,则会引发错误。


至于y === 2,这是因为var y;内没有C,因此y = 2设置了window.y,并且在全局范围内this === window 1}}。


  

这个构造的用法/目的是什么?

  • comma operator ,允许您在一行上执行多个表达式。
  • 函数表达式对很多东西很有用,可以立即调用它们,这样你就可以有一个闭包,或者将它们存储在变量中等等。

答案 1 :(得分:4)

在括号中包装代码会强制将其解析为表达式。

var关键字仅作为语句有效,因此会产生语法错误。

函数声明可以是语句(创建一个提升变量)或表达式(不创建任何变量)。

因此,将函数包装在括号中会将其转换为函数表达式,而不会创建外部可见的名称。

有关详细信息,请参阅here