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文档才能执行.可以有两种方式完成这一 ...
随机推荐
- ejb与javabean的区别总结
EJB的英文全称是企业级的JavaBean 两者是完全不同的 JavaBean是一个组件,而EJB就是一个组建框架 JavaBean面向的是业务逻辑和表示层的显示,通过编写一个JavaBean,可以将 ...
- redis批量删除key 命令
redis-cli -n 数据库编号 -a 密码 keys "过滤条件" | xargs redis-cli -n 数据库编号 -a 密码 del Demo: redis-cli ...
- IPV6的链路本地地址和站点本地地址的不同
转帖 中关村 http://ask.zol.com.cn/x/2230274.html IPV6涉及到一个概念,link-local address, 中文叫“链路本地地址”,它的前缀是FE80::/ ...
- Linux服务器学习(二)
昨天简单了解了linux的基础命令,今天学习linux搭建环境(安装文件,配置文件)及权限操作. 一.搭建lnmp环境 lnmp指Linux+Nginx+Mysql+PHP Ubuntu安装文件命令为 ...
- object & over-write
object & over-write
- APP 测试 与 WEB 测试的本质区别
单纯从功能测试的层面上来讲的话,APP 测试.web 测试 在流程和功能测试上是没有区别的 根据两者载体不一样,则区别如下: 1.系统结构方面 web项目,b/s架构,基于浏览器的:web测试只要更新 ...
- 关于nginx的一点记录
(1) 安装nginx官网下载:http://nginx.org下载适合Windows的安装包,是一个压缩包,直接解压就可以了. (2) 启动nginx有三种方式启动:a. 双击nginx.exe图标 ...
- 【Java并发编程】之十:使用wait/notify/notifyAll实现线程间通信的几点重要说明
在Java中,可以通过配合调用Object对象的wait()方法和notify()方法或notifyAll()方法来实现线程间的通信.在线程中调用wait()方法,将阻塞等待其他线程的通知(其他线程调 ...
- python 查看与更换工作目录
1. 进入python控制台 2. 查看工作路径,需要导入os包: import os 3. 查看工作路径的命令: os.getcwd() 4. 修改工作路径的命令: os.chdir("d ...
- Java中线程同步的理解 - 其实应该叫做Java线程排队
Java中线程同步的理解 我们可以在计算机上运行各种计算机软件程序.每一个运行的程序可能包括多个独立运行的线程(Thread). 线程(Thread)是一份独立运行的程序,有自己专用的运行栈.线程有可 ...