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

Javascript: rounded parentheses surrounding comma separated expressions

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

试试这个:

1
2
3
4
5
6
7
8
>( 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

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

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

然后实例化:

1
2
3
4
5
6
7
8
>var c=new C()
i am x
hello
undefined
>c.y
undefined
>this.y
2

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

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

多一个:

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

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


命名函数不是"被困在里面",因为它们不是函数声明(使用function作为语句),它们实际上是函数表达式(使用function作为运算符)。这意味着它们的名称不会成为当前名称空间中对它们自身的引用。

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

对于y === 2,这是因为你在C中没有var y;,所以y = 2设置window.y,并且在全局范围this === window中。

whats the usage / purpose of this construct?

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


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

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

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

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

有关更多信息,请参阅此处。