zoukankan      html  css  js  c++  java
  • JavaScript语法对{}的奇葩处理

    JavaScript的语法有多坑,算是众人皆知了。

    今天看到vczh的这条微博:http://weibo.com/1916825084/B7qUFpOKb ,

     代码如下:

    {} + [];    // 0
    [] + {};    // "[object Object]"
    {} + [] == [] + {};    // false
    ({} + [] == [] + {});    // true

    这么蛋疼的语法坑估计也只有 JavaScript 这样的奇葩才有。

    相信对于绝大部分不研究 JavaScript 编译器的童鞋,根本无法理解。(至少我也是觉得不可思议)

    后来看到有人在转发中贴出了这篇文章,才有点恍然大悟!

    下面,我们先看看这个代码:

    {
        a: 1
    }

    相信大部分童鞋,第一眼都会认为这是一个 对象直接量

    那这个代码呢?

    {
        var a = 1;
    }

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

    显然不会!细想一下,我们就会明白到,这是一个 语句块

    if (1) {
        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。

    参考资料:

    http://typeof.net/s/jsmech/02.html

    本文作者:Maple Jan

    本文链接:http://www.cnblogs.com/maplejan/p/3768010.html

  • 相关阅读:
    MySQL日期数据类型、时间类型使用总结
    mybatis中的mapper接口文件以及example类的实例函数以及详解
    IDEA 的快捷键简单使用
    Enum强制转换
    保存信息到配置文件
    通过配置文件判断程序首次启动
    StackPanel Binding
    RadGridView样式设置与Binding
    虚拟键盘输入之回车事件绑定与鼠标点击事件绑定
    数据库基础之-范式
  • 原文地址:https://www.cnblogs.com/maplejan/p/3768010.html
Copyright © 2011-2022 走看看