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

IT技术 javascript node.js firebug
2021-01-25 15:19:01

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

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

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

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

此外,我想了解 Node.js 和 Firebug 之间存在一些不一致之处。

萤火虫:

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

节点.js:

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

2个回答

让我们看看语言语法,好吗?第 12 节,声明

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

这是一种非常奇特的说法,语句可以是块、变量语句、空语句、表达式语句或许多其他内容。请注意,第一个选项有一个“块”:

Block :
    { StatementList(opt) }

StatementList :
    Statement
    StatementList Statement

这又是一种奇特的说法,块是 a {,可选地后跟一堆语句,后跟 a }

这就是您在示例中看到的内容:在 JavaScript 解析器认为您拥有的内容可能是一个对象字面量之前(在 下某处定义ExpressionStatement,“语句”可能是第 4 件事),它首先认为您有一个“块” '。

编辑:如果你愿意,你可以在 JavaScript 引擎的源代码中看到它:

关于你的第二个问题,这个问题已经详细介绍用一句话总结:Node.js 将您的输入视为表达式(因此它不能是“块”),而 Firebug/Chrome 开发工具将其视为“语句”。

好吧,表达式中不允许使用分号,因此它不会被评估为表达式,而是被评估为语句。
2021-03-14 15:19:01
好的,我现在看到了 - 节点明确检查对象文字(领先{)的情况。我不认为我会这样做(最不令人惊讶的原则)但无论如何。
2021-03-17 15:19:01
这就是为什么摘要是在一个句子中。Benjamin Gruenbaum 的回答更详细:REPL 首先尝试将它作为表达式执行,如果抛出 SyntaxError,它会转为直接eval为什么?耸耸肩
2021-03-18 15:19:01
我认为 Node REPL 将输入视为表达式是不正确的 - 例如,您可以在 REPL 中输入for循环。
2021-03-22 15:19:01
感谢您提供有趣的参考资料!我仍然不明白为什么 Node.js 示例中的分号很重要。
2021-04-10 15:19:01

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

(其实当然,当{出现后的像头条款if或者while,然后{}是一个空的块太大,但是这不是有趣的情况。)

因此,在任何其他上下文中,例如对函数说一个参数:

foo({});

the{}被解释为空对象字面量。

这种情况类似于function关键字作为语句中的第一件事时被区别对待的方式语法有歧义,解析器用固定规则解决问题。

@EllaShar 我对 Node 不太熟悉,但它基本上只是将您键入的字符串传递给eval(),但它以某种方式改变了句法上下文。如果你输入;{}+[]Node,你就会0像在 Firebug 中一样。
2021-03-12 15:19:01
你如何解释第一个 Node.js 示例?谢谢!
2021-04-04 15:19:01