详解JavaScript语法对{}处理的坑爹之处

2019-12-21,,,

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。

您可能感兴趣的文章:

  • javascript之函数直接量(function(){})()
  • js函数使用技巧之 setTimeout(function(){},0)
  • JavaScript ( (__ = !$ + $)[+$] + ({} + $)[_/_] +({} + $)[_/_] )
  • js 中{},[]中括号,大括号使用详解
  • js面向对象设计用{}好还是function(){}好(构造函数)
  • 解决css和js的{}与smarty定界符冲突问题的两种方法
  • 解析Javascript中大括号“{}”的多义性
  • javascript的 {} 语句块详解

《详解JavaScript语法对{}处理的坑爹之处.doc》

下载本文的Word格式文档,以方便收藏与打印。