在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
因此,命名函数既不能在括号内引用。
答案 0 :(得分:6)
命名函数不是“被困在里面”,因为它们不是函数声明(使用function
as a statement),它们实际上是函数表达式 (使用function
as an operator)。这意味着它们的名称不会成为当前名称空间中对它们自己的引用。
某些关键字/标记只能用作语句,例如var
,因此如果您尝试在解释器期望作为表达式的条件中使用它们,则会引发错误。
至于y === 2
,这是因为var y;
内没有C
,因此y = 2
设置了window.y
,并且在全局范围内this === window
1}}。
这个构造的用法/目的是什么?
,
允许您在一行上执行多个表达式。答案 1 :(得分:4)
在括号中包装代码会强制将其解析为表达式。
var
关键字仅作为语句有效,因此会产生语法错误。
函数声明可以是语句(创建一个提升变量)或表达式(不创建任何变量)。
因此,将函数包装在括号中会将其转换为函数表达式,而不会创建外部可见的名称。
有关详细信息,请参阅here。