JavaScript语法对{}的奇葩处理
JavaScript的语法有多坑,算是众人皆知了。
今天看到vczh的这条微博:http://weibo.com/1916825084/B7qUFpOKb ,

代码如下:
{} + []; //
[] + {}; // "[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 () {} 不是函数声明,也不是函数表达式。
到这里,大家应该对 {} 的奇葩处理有了基本的概念。我们再看回文章开始所提到的几条语句:
{} + []; //
[] + {}; // "[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
JavaScript语法对{}的奇葩处理的更多相关文章
- JavaScript:JavaScript语法的详细介绍
JavaScript语法:只要Java会了,基本上javascript语法就会了. ——变量的定义 ——程序的结构控制 ——数组操作 ——函数的定义即使用 基本的test.html代码如下,它会导入下 ...
- javascript语法详解
javascript语法:运算符 条件语句if...else... 条件语句switch 循环语句for 循环语句while 跳转语句 js运算符 1.算数运算符:+ - * % / ++ ...
- When Colon Scripting is comming(JavaScript语法扩充)
当冒号脚本来临-- JavaScript语法扩充 连续好几夜的不能安眠,得出结论就是,未来语言未来的编译器应该是支持语法定制规则和语法扩展的,这样使得编程语言不断进化以更利于人类使用!of cours ...
- Javascript语法基础
Javascript语法基础 一.基本数据类型 JavaScript中支持数字.字符串和布尔值三种基本数据类型: 1.数字 数字型是JavaScript中的基本数据类型.在JavaScript ...
- JavaScript中的各种奇葩问题
原文:JavaScript中的各种奇葩问题 JavaScript浮点数 var a = (0.1 + 0.2) + 0.3; var b = 0.1 + (0.2 + 0.3); console.lo ...
- JavaScript语法细节——引用与复制
原文:JavaScript语法细节--引用与复制 我们都知道,JS中变量的赋值有两种方式,最近在折腾自己写的标签栏插件,碰到了很多平时没注意的问题.正好,那边处理清楚了,稍微整理一下关于引用与复制相关 ...
- 第九十八节,JavaScript语法、关键保留字及变量
JavaScript语法.关键保留字及变量 学习要点: 1.语法构成 2.关键字保留字 3.变量 任何语言的核心都必然会描述这门语言最基本的工作原理.而JavaScript的语言核心就是ECMAScr ...
- JavaScript 语法
一.JavaScript简介 1.JavaScript是个什么东西? 它是个脚本语言,需要有宿主文件,它的宿主文件是HTML文件. 2.它与Java什么关系? 没有什么直接的联系,Java是Sun公司 ...
- JavaScript DOM 编程艺术(1)---> JavaScript语法
一. JavaScript语法目录 语法 操作 条件语句 循环语句 函数 对象 二. 具体内容 2.1 语法 javaScript代码要通过HTML/XHTML文档才能执行.可以有两种方式完成这一 ...
随机推荐
- 由于MDK5.0A没有STM32F103程序错误 stm32f10x.h(298): error: #67: expected a "}"
转自:http://blog.163.com/lby147612@126/blog/static/17041045220150130438428/ 由于MDK4.72A没有STM32F030,所以升级 ...
- MySQL 5.6 & 5.7最优配置文件模板
Inside君整理了一份最新基于MySQL 5.6和5.7的配置文件模板,基本上可以说覆盖90%的调优选项,用户只需根据自己的服务器配置稍作修改即可,如InnoDB缓冲池的大小.IO能力(innodb ...
- P2219 [HAOI2007]修筑绿化带
我是题面 这道题跟理想的正方形很像,不大明白蛤OI是怎么想的,一年出两道这么相近的题 这道题有两个矩形,所以就有了两种做法(说是两种做法,其实只是维护的矩形不同) 一种是维护大矩形,一种是维护小矩形, ...
- java并发编程中CountDownLatch和CyclicBarrier的使用
在多线程程序设计中,经常会遇到一个线程等待一个或多个线程的场景,遇到这样的场景应该如何解决? 如果是一个线程等待一个线程,则可以通过await()和notify()来实现: 如果是一个线程等待多个线程 ...
- java 自动装箱
Java 编译器把原始类型自动转换为封装类的过程称为自动装箱(autoboxing),相当于调用包装类的valueof方法.举例说明: 源码: 编译之后的代码:
- MT【153】缩小包围圈
(清华2017.4.29标准学术能力测试3) 集合$S=\{1,2,\cdots,25\}$,$A\subseteq S$,且$A$ 的所有子集中元素之和不同.则下列选项正确的有( ) A. ...
- 【BZOJ3518】点组计数
Description 平面上摆放着一个\(n*m\)的点阵(下图所示是一个3*4的点阵).Curimit想知道有多少三点组(a,b,c)满足以a,b,c三点共线.这里a,b,c是不同的3个点,其顺序 ...
- Mac上安装python3并设置SublimeREPL插件默认运行python3
1.安装python3 $ brew search python $ brew install python3 这里安装完后不需要单独添加环境变量,程序已经处理好,可以直接运行python3命令. $ ...
- 控制对象的创建方式(禁止创建栈对象or堆对象)和创建的数量
我们知道,C++将内存划分为三个逻辑区域:堆.栈和静态存储区.既然如此,我称位于它们之中的对象分别为堆对象,栈对象以及静态对象.通常情况下,对象创建在堆上还是在栈上,创建多少个,这都是没有限制的.但是 ...
- Android 捕获组合键
android中捕获组合键http://blog.csdn.net/wenlibin1985/article/details/5579359 Android组合键http://www.eoeandro ...