JavaScript 中花括号 {} 的二义性与解析陷阱

作者:闭包旅人

时间:2026-10-28

浏览:83

JavaScript 语法中 {} 存在二义性:语句开头被解析为语句块,否则为对象直接量。本文通过 {} + [] 等示例,解析编译器处理逻辑及标签语句机制,揭示常见语法陷阱。

文章目录

JavaScript 中花括号 {} 的二义性与解析陷阱

JavaScript 语法的复杂性广为人知。

首先通过一张示意图进行说明。

JavaScript 中花括号 {} 的二义性与解析陷阱

具体代码示例如下:

代码片段展示:

{} + []; // 返回 0
[] + {}; // 返回 "[object Object]"
{} + [] == [] + {}; // 结果为 false
({} + [] == [] + {}); // 结果为 true

这种令人头疼的语法特性,在 JavaScript 中确实较为罕见。

对于大多数不深入研究 JavaScript 编译原理的开发者而言,这很难理解(至少对我来说也是如此)。

经过查阅相关资料后,才逐渐理清了思路。

接下来,我们先分析这段代码:

代码展示:

{
a: 1
}

大多数开发者第一眼可能会将其误认为是一个对象直接量。

那么这段代码呢?

代码展示:

{
var a = 1;
}

浏览器会提示语法错误吗?

显然不会。仔细分析可知,这实际上是一个语句块。

代码展示:

if (isNumber) {
var a = 1;
}


花括号二义性与编译器处理逻辑

由此可以看出,JavaScript 中以 { 开头的代码存在二义性。

JavaScript 编译器如何处理这种二义性?

为了解决这一问题,ECMA 采取了简单直接的方法:在语法解析阶段,如果一个语句以「{」开头,则将其解释为语句块。

这确实是一种令人诟病的处理方式。

既然都是语句块,为什么 {a:1} 却没有语法错误?

在此情况下,a 被解析器识别为标签。标签用于配合 break 和 continue 语句进行定向跳转。

因此,以下写法会抛出异常:

代码展示:

{
a: function () {}
}

因为 function () {} 既不是函数声明,也不是函数表达式。

具体代码示例解析

至此,大家对 {} 的特殊处理应有基本了解。我们回到文章开头提到的几条语句:

代码展示:

{} + []; // 返回 0
[] + {}; // 返回 "[object Object]"
{} + [] == [] + {}; // 结果为 false
({} + [] == [] + {}); // 结果为 true

第一条中,由于 {} 是语句块,代码可理解为:

代码展示:

if (1) {}
+[]

因此返回值为 0。

第二条中,{} 不在语句开头,故视为正常的对象直接量。空数组与空对象直接相加,返回 "[object Object]"。

理解了前两条,第三条无需多言。

第四条中,因以 () 开始,第一个 {} 被解析为对象直接量,故两条公式相等,返回 true。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章