浅析Javascript的自动分号插入(ASI)机制


Posted in Javascript onSeptember 29, 2016

前言

相信从事过C#和Java的大家都知道分号是用作断句(EOS,end of statement)的,而且必须加分号,否则编译就不通过了。但JavaScript由于存在ASI机制,因此允许我们省略分号。ASI机制不是说在解析过程中解析器自动把分号添加到代码中,而是说解析器除了分号还会以换行为基础按一定的规则作为断句的依据,从而保证解析的正确性。

规范理论

es5 标准定义了自动分号插入规则,包括以下三个基本规则加两个前置条件:

前置条件

1、如果插入分号后解析结果是空语句,那么不会自动插入分号。

例子:(空语句,else 前不加分好)

if (a > b) 
else c = d

2、如果插入分号后它成为 for 语句头部的两个分号之一,那么不会自动插入分号。

例子:(不会加分号)

for (a; b 
)

基本规则

左到右解析程序,当遇到一个不符合任何文法产生式的 token(叫做 违规 token(offending token)),那么只要满足下面条件之一就在违规 token 前面自动插入分号。

     1、至少一个 LineTerminator 分割了违规 token 和前一个 token

     2、违规 token 是 }。

例子:(1、2不符合任何产生式,并且之间存在 LineTerminator,因此在违规 token 2前加了分好,2和}则是因为违规 token 是 }所以加了分号)

{ 1
2 } 3
{ 1
;2 ;} 3;

左到右解析程序,tokens 输入流已经结束,当解析器无法将输入 token 流解析成单个完整 ECMAScript 程序 ,那么就在输入流的结束位置自动插入分号。

对于受限产生式,也就是下面的5个,我们把产生式 [no LineTerminator here]后面的 token 叫做受限 token,如果在 token 和 受限 token 间存在了至少一个 LineTerminator,那么会在受限 token 前自动加上 token

受限的产生式只限如下5个:

PostfixExpression : 

LeftHandSideExpression [no LineTerminator here] ++ LeftHandSideExpression [no LineTerminator here] -- 

ContinueStatement : 

continue [no LineTerminator here] Identifier; 

BreakStatement : 

break [no LineTerminator here] Identifier; 

ReturnStatement : 

return [no LineTerminator here] Expression; 

ThrowStatement : throw [no LineTerminator here] Expression; 

归纳

避免 ASI 带来的问题

     1、后缀运算符 ++ 或 -- 和它的操作数应该出现在同一行。

     2、return throw 语句的表达式开始位置应该和 return throw token 同一行。

     3、break 或 continue 语句的标示符应该和 break continue token 同一行。

何时加分号

无分号党(懒人党)想要不加分号,那么就需要知道什么时候应该要加分号。网上的一篇文章归纳了 NO ASI 并且会出现错误的几种情况,在这几种情况下我们是要加分号的。下面是对应的描述:

在以 ([/+- 开头的语句前加分号(由于正常写法均不会出现以 .,*% 作为语句开头,因此只需记住前面5个即可,你看能懒则懒哦)

不过这里只考虑了换行的情况,其实 ASI 还存在不换行的情况,这就要根据标准里的三条规则行事了!

知道了这点,其实我们就可以省略大部分的分号了。但是也不强求,因为这还是要根据个人习惯以及团队风格走的。

小补充

为什么自执行函数前要加分号?

主要是应对代码合并压缩时,由于缺少分号;带来的错误。知道了上面的规则,在 ( 开头的行前加分号就可以避免错误了。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

Javascript 相关文章推荐
event.srcElement 用法笔记e.target
Dec 18 Javascript
Prototype的Class.create函数解析
Sep 22 Javascript
jQuery Form 页面表单提交的小例子
Nov 15 Javascript
基于jQuery创建鼠标悬停效果的方法
Mar 07 Javascript
JavaScript代码实现左右上下自动晃动自动移动
Apr 08 Javascript
javascript实现页面滚屏效果
Jan 17 Javascript
jquery请求servlet实现ajax异步请求的示例
Jun 03 jQuery
js Date()日期函数浏览器兼容问题解决方法
Sep 12 Javascript
基于vue中css预加载使用sass的配置方式详解
Mar 13 Javascript
在vue中使用v-bind:class的选项卡方法
Sep 27 Javascript
Angular6项目打包优化的实现方法
Dec 15 Javascript
Nuxt pages下不同的页面对应layout下的页面布局操作
Nov 05 Javascript
完美解决IE9浏览器出现的对象未定义问题
Sep 29 #Javascript
JSON 对象未定义错误的解决方法
Sep 29 #Javascript
Node.js检测端口(port)是否被占用的简单示例
Sep 29 #Javascript
json定义及jquery操作json的方法
Sep 29 #Javascript
JavaScript中apply方法的应用技巧小结
Sep 29 #Javascript
老生常谈javascript变量的命名规范和注释
Sep 29 #Javascript
浅谈javascript:两种注释,声明变量,定义函数
Sep 29 #Javascript
You might like
浅析php插件 HTMLPurifier HTML解析器
2013/07/01 PHP
php实现分页显示
2015/11/03 PHP
PHP5.2中PDO的简单使用方法
2016/03/25 PHP
将PHP的session数据存储到数据库中的代码实例
2016/06/24 PHP
浅谈php中的访问修饰符private、protected、public的作用范围
2016/11/20 PHP
PHP设计模式之单例模式原理与实现方法分析
2018/04/25 PHP
在Laravel中使用GuzzleHttp调用第三方服务的API接口代码
2019/10/15 PHP
PHP实现微信提现功能(微信商城)
2019/11/21 PHP
jQuery中与toggleClass等价的程序段 以及未来学习的方向
2010/03/18 Javascript
基于JQUERY的两个ListBox子项互相调整的实现代码
2011/05/07 Javascript
js获取当前时间显示在页面上并每秒刷新
2014/12/24 Javascript
分享9个最好用的JavaScript开发工具和代码编辑器
2015/03/24 Javascript
jQuery ajax分页插件实例代码
2016/01/27 Javascript
AngularJS入门教程之迭代器过滤详解
2016/08/18 Javascript
AngularJS页面传参的5种方式
2017/04/01 Javascript
JavaScript编写棋盘覆盖代码详解
2017/08/28 Javascript
使用 Vue 绑定单个或多个 Class 名的实例代码
2018/01/08 Javascript
基于Echarts图表在div动态切换时不显示的解决方式
2020/07/20 Javascript
原生js+canvas实现验证码
2020/11/29 Javascript
[02:53]DOTA2英雄昆卡基础教程
2013/11/25 DOTA
[52:02]DOTA2-DPC中国联赛 正赛 Phoenix vs Dragon BO3 第二场 2月26日
2021/03/11 DOTA
Python性能优化技巧
2015/03/09 Python
Python Requests模拟登录实现图书馆座位自动预约
2018/04/27 Python
使用anaconda的pip安装第三方python包的操作步骤
2018/06/11 Python
Python用Try语句捕获异常的实例方法
2019/06/26 Python
python opencv minAreaRect 生成最小外接矩形的方法
2019/07/01 Python
浅析Django中关于session的使用
2019/12/30 Python
使用Python第三方库pygame写个贪吃蛇小游戏
2020/03/06 Python
torchxrayvision包安装过程(附pytorch1.6cpu版安装)
2020/08/26 Python
德国汽车零件和汽车配件网上商店:kfzteile24
2018/11/14 全球购物
会计电算化个人求职信范文
2014/01/24 职场文书
公司委托书范本
2014/04/04 职场文书
文艺演出策划方案
2014/06/07 职场文书
德育标兵事迹材料
2014/08/24 职场文书
舞蹈社团活动总结
2015/05/07 职场文书
如何制作自己的原生JavaScript路由
2021/05/05 Javascript