JS何时将{}解释为空块而不是空对象?

我正在读这个问题的答案(关于“wat”video),它说:

  1. {}+[]
    这被解释为一个空的代码块,一元加号和空数组。 第一部分什么都不做,数组被转换为它的元素的逗号分隔string(空数组为空string),然后被转换为数字(空string被转换为0),因此为0。

我目前正在从“权威指南”中学习JS,所以我试图真正理解这样的事情。

我的问题是,JS什么时候决定将{}解释为一个空的代码块,而不是一个空的对象?

另外,Node.js和Firebug之间还有一些不一致之处,我想了解。

萤火虫:

用于<code> {} [] </ code>和<code>({} [])的Firebug控制台输出</ code>

Node.js的:

用于<code> {} [] </ code>和<code>({} [])的Node.js输出</ code>

让我们来看看语言语法,对吗? 第12节,声明 :

 Statement : Block VariableStatement EmptyStatement ExpressionStatement ...lots of other stuff... 

这是一个非常奇特的方式,说一个语句可以是一个块,一个variables语句,一个空语句,一个expression式语句,或者其他很多东西。 请注意,第一个选项是“Block”:

 Block : { StatementList(opt) } StatementList : Statement StatementList Statement 

这又是一个奇怪的方式,说一个块是一个{ ,后面跟着一堆语句,接着是一个}

这就是你在例子中看到的东西:在JavaScriptparsing器认为你所拥有的东西可能是一个对象字面值(它是在ExpressionStatement下的某个地方定义的,“Statement”可能是第四个)之前,它首先认为你有一个“块'。

编辑:如果你想,你可以看到它住在一个JavaScript引擎的源代码:

  • 在Chrome的JavaScript引擎V8中,我们进入了Parser::ParseStatement 。 它检查的第一件事是我们是否在{ ,如果它是,parsing为块。
  • 在SpiderMonkey,Firefox的JavaScript引擎中,我们从Parser::statement再次看到第一个检查对象{和parsing它作为块语句。

关于你的第二个问题, 这个问题已经被详细的介绍了 。 用一句话来总结一下:Node.js把你的input看作是一个expression式(因此它不能成为'Block'),而Firebug / Chrome开发工具把它看作是一个'Statement'。

当新语句中的第一个标记为{ ,则{}被解释为空块。

(实际上当{出现在ifwhile类的标题子句之后,那么{}也是空的块,但这不是有趣的情况)。

因此,在任何其他情况下,比如说一个函数的参数:

 foo({}); 

{}被解释为一个空的对象文字。

这种情况类似于function关键字在语句中的第一件事情时的处理方式。 语法有歧义,parsing器用固定规则解决问题。