auto semicolon insertion 自动分号补齐的坑
今天发现js自动分号补齐的坑,来看如下两段代码:
function Hello(){return{name: ’JavaScript’};
}alert(Hello());//输出undefined
function Hello(){return{name: ’JavaScript’};
}alert(Hello());//输出 [object Object]
略看代码,差不多,但是输出却不一样。仔细看看第一段代码return后面多了个换行。我们平时写后端代码也经常有会这样换行后花括号左对齐的写法。但是在js这里这样写却有不同的输出。这种机制叫分号自动补齐机制( auto semicolon insertion,简称ASI )。
知乎上有大神关于这个机制的解释:
在ASI的机制中有一类语句叫做restricted productions(不知道中文叫啥)。简单来说,就是组成这类语句的两个token当中不允许出现换行符 \n。如果在第一个token后面遇到了换行符,则判断语句结束,插入分号。restricted productions包括:
- return xxx (xxx是要返回的对象)
- throw xxx(xxx是要抛出的错误对象)
- break / continue xxx(xxx是循环的标签)
- 作为后缀的 ++ / --
其中前几个关键词还是挺容易记的,最后一条的原因是需要区分以下情况:
a
++
b
因为++/--既可以作为前缀又可以作为后缀,在这样的情况下作为后缀解析会遇上换行符,所以只能作为b的前缀,自动插入分号后变成:
a; ++b;
回到原题,Douglas Crockford认为 { 应该写在行尾,是为了避免换行符导致return直接返回undefined。
篇外:关于分号 ------------------------------------------------------------------------------------------------
很多人觉得ASI坑太多了所以提倡永远手动加分号,这样就不用费心去研究ASI的规则了。但事实上,即使永远手动加分号,你依然会被restricted productions这条规则坑,因为它是在你不想要分号的地方给你插入分号。所以不管你喜不喜欢分号,都最好花点时间好好了解一下ASI的规则。而一旦你知道了ASI所有的坑,不写分号其实是很简单的。
ASI真正需要注意的坑只有两个,restricted productions是其一,另一个就是当下一行开头是 ( [ / 这三个字符之一的时候:
a = b
(function () { ... }())
会被解析成
a = b(function () {...}());
换言之,( ) 会被看做是在调用函数b。同理,[ ] 会被看做是在获取b的属性,而被斜杠坑的情况则要求更苛刻一些:
a = b
/Error/i.test(str) && doSomething()
第二行的写法本身比较少见,但也不是不可能。结果会被解析成:
a = b / Error / i.test(str) && doSomething();
斜杠被解析成了除号!
要躲开这个坑,其实真的挺简单,只要尽量别用这三个字符作为一行开头就行了。事实上遇到比较多的也只有括号开头。真的避不开的话,可以在行头手动加个分号:
a = b
;(function () { ... }())
额外的一点是在for循环声明里面的分号是永远不能省的,ASI不会在for循环声明中插分号,但一般正常人不会把for的声明分三行写吧...
每次我看到 “javascript分号坑很多,所以应该永远加分号” 这样的说法总是有些不屑的,因为永远加分号并不是避免错误的办法,搞懂ASI是怎么回事才是。只要理解了这里说的两个坑,javascript里99%的分号都是不必要的。
转载于:https://www.cnblogs.com/zhangcybb/p/7018576.html
auto semicolon insertion 自动分号补齐的坑相关推荐
- [翻译]JavaScript秘密花园 - Type Casting,undefined,eval,setTimeout,Auto Semicolon Insertion - 全部完成PDF打包下载
JavaScript Garden - 原文 JavaScript Garden - 中文翻译 PDF打包下载 类型转换 JavaScript 是弱类型语言,所以会在任何可能的情况下应用强制类型转换. ...
- linux快捷命令补齐,Linux Shell简介——自动补齐/命令行的历史记录/编辑命令行/可用的 Shell 快捷方式.doc...
Linux Shell简介--自动补齐/命令行的历史记录/编辑命令行/可用的 Shell 快捷方式 Unix (及后继者 Linux)在命令行下面诞生,因此,Unix 中的命令行有许多非常实用的功能. ...
- ios-晋级之路 CocoaPods引用第三方库不import不自动补齐
对于CocoaPods不自动补齐解决方案如下 选择工程的 Target -> Build Settings 菜单,找到\"User Header Search Paths\" ...
- mysql 自动补齐 表名,列名 方法, 重启mysql方法
1.mysql自动补齐方法 方法一.修改my.cnf vi /etc/my.cnf [mysql] auto-rehash #添加auto-rehash 注:修改 #no-auto-r ...
- Geany 代码自动补齐功能设置
很多人用 geany 感觉不方便,有一部分就是相比于 pycham 的自动补齐功能不好使. 现在给大家看下自动补齐功能设置方法,设置完后用起来非常方便哦. Geany 代码自动补全设置: 默认出现自动 ...
- Jupyter 编写python代码实现代码自动补齐功能设置实例演示
Jupyter 代码自动补齐功能 第一章:启用代码自动补齐功能 ① 安装工具包 ② 重启 Jupyter 服务 ③ 功能设置 ④ 效果展示 ⑤ cmd 安装工具包详细过程展示 第一章:启用代码自动补齐 ...
- sql server 语句自动补齐
sql2008 sql语句自动补齐功能 sql2008的命令自动补齐功能在哪设置 包括查询的表明自动补齐 不想用插件 这个好像2008自带的有这个功能 难道我装的版本不对 楼主说的是自动联想功能吧,任 ...
- 如何设置使windows(dos)命令中目录和文件可以自动完成和补齐
1. 如果只是临时使用,可以用cmd /f打开命令窗口 2.如果想永久使用 1)在运行窗口输入regedit 2)找到键值HKEY_LOCAL_MACHINE/Software/Microsoft/C ...
- 输入框限制只能输入数字,正数、负数、0,最多两位小数;数字输入框可以输入负数,并最多保留两位小数;el-number-input去掉四舍五入和自动补齐小数;
场景: –要求1:输入框只能输入数字,可以使正数.负数.0,小数点最多保留两位. –要求2:不需要自动补齐小数点,也不需要自动四舍五入. element-ui的数字输入框el-input-number ...
- 【转】Emacs -- 自动补齐
1. Emacs 自带的hippie-expand (参考的是王垠的) hippie-expand是 Emacs 自带的功能, 把M-/ 绑定到 hippie-expand,在.emacs文件中加入 ...
最新文章
- this.options[selectedIndex]的使用
- C++从键盘读取字符
- webstorm github怎么用_前端开发神器WebStorm发布最新版本2019.3,代码完成更加智能...
- 汇编语言 ADC指令和SBB指令
- 图解OpenLayers-2.13.1入门实例
- Linux疑难杂症解决方案100篇(十)-uptime命令查看linux系统负载
- linux 内核 hrtimer,hrtimer在Linux内核中重复任务
- 又一数据库高危漏洞爆出,数据安全如何有效保障?
- ISE_FIFO_IP核接口测试(一)
- 开发WCF/Silverlight须知
- Python网络编程之基于socket实现文件上传
- 震惊,线程共享变量使用不当引发血案
- 光耦p621引脚图_p421光耦引脚图和代换
- matlab逆变换法产生随机数_用matlab产生随机数
- LSV又新增13个地质图!量测对比分析全都能搞定
- RabbitMQ 中的 VirtualHost 该如何理解
- 全国计算机access二级真题,最新全国计算机二级access历年真题.doc
- vue中用echarts 绘制geo 中国地图
- 海通股票交易系统通道接口错误怎么办
- ajax提交,form表单提交,onsubmit=return checksubmit()提交验证