2013-08-18 60 views
4

在JS控制台上播放我遇到了一个奇怪的语法。我不知道是否有人能告诉我更多的对..Javascript:围绕逗号分隔表达式的圆括号

试试这个:

>(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: Unexpected token var

所以逗号分隔的表达式括号内进行评估,分配恰好是反对全局作用域,但名为函数声明引用保持被困在里面就像关闭 更多... 把该行放在函数声明中调用新的

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 

所以在命名的功能不能被引用既没有括号内。

+0

命名的功能都没有“媚惑”,因为它们不是_function declarations_(使用'function'作为语句),所以它们实际上是_function expressions_(使用'function'作为操作符)。 –

回答

5

命名的功能都没有“媚惑”,因为他们不是函数声明(使用function as a statement),它们实际上是功能(使用function as an operator)表达式。这意味着他们的名字不会成为当前名字空间中的自身引用。


某些关键字/令牌只能用作语句,如var,因此如果试图在其解释预计将一个表达的条件使用它们引发错误。


至于y === 2,这是因为你没有var y;C,所以y = 2window.y,并且在全球范围内this === window


whats the usage/purpose of this construct?

  • comma operator ,可以让你在同一行做多的表现。
  • 函数表达式是一个伟大的很多有用的东西,是它会立即调用它们让你有一个关闭,或存储它们的内部变量等
+1

另外:命名函数表达式的名称应该只在函数内部可见(以允许递归),因此f未定义的错误。 – bfavaretto

4

用圆括号包装代码迫使它被解析为一个表达式。

var关键字仅作为语句使用,所以会产生语法错误。

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

因此,将函数包装在括号中会将它变成一个函数表达式,它不会创建一个外部可见的名称。请参阅here

+0

非常好的文章! 确定关于声明vs表达式.. 甚至当在“另一个这样”的用例中(除了自我执行函数用于隔离闭包)进行评估时,对全局对象的赋值又如何呢? – aleclofabbro

+0

@aleclofabbro:我不确定你在问什么。 – SLaks

+0

我的意思是(x = 1,y = 2)总是隐式地将x和y分配给globalobject(globalobject.x == 1和globalobject.y == 2),即使它是在构造函数内部求值 – aleclofabbro

相关问题