浅析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 相关文章推荐
javascript 面向对象编程 function也是类
Sep 17 Javascript
jquery 读取页面load get post ajax 四种方式代码写法
Apr 02 Javascript
ASP.NET jQuery 实例4(复制TextBox的文本到本地剪贴板上)
Jan 13 Javascript
AngularJS单选框及多选框实现双向动态绑定
Jan 13 Javascript
JSON字符串和JSON对象相互转化实例详解
Jan 05 Javascript
vue中v-cloak解决刷新或者加载出现闪烁问题(显示变量)
Apr 20 Javascript
微信小程序非swiper组件实现的自定义伪3D轮播图效果示例
Dec 11 Javascript
一个因@click.stop引发的bug的解决
Jan 08 Javascript
使用express获取微信小程序二维码小记
May 21 Javascript
javascript设计模式 ? 代理模式原理与用法实例分析
Apr 16 Javascript
vuex Module将 store 分割成模块的操作
Dec 07 Vue.js
javascript代码实现简易计算器
Jan 25 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
日本因肺炎疫情影响,这几部动漫推延播放!
2020/03/03 日漫
本地机apache配置基于域名的虚拟主机详解
2013/08/10 PHP
zend framework框架中url大小写问题解决方法
2014/08/19 PHP
纯js实现的论坛常用的运行代码的效果
2008/07/15 Javascript
IE和Firefox下event事件杂谈
2009/12/18 Javascript
javascript 的Document属性和方法集合
2010/01/25 Javascript
javascript拓展DOM操作 prependChild insertAfert
2010/11/17 Javascript
用JQuery 判断某个属性是否存在hasAttr的解决方法
2013/04/26 Javascript
在Iframe中获取父窗口中表单的值(示例代码)
2013/11/22 Javascript
淘宝网提供的国内NPM镜像简介和使用方法
2014/04/17 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享
2016/05/09 Javascript
JS判断是否在微信浏览器打开的简单实例(推荐)
2016/08/24 Javascript
微信小程序实现弹出层效果
2020/05/26 Javascript
微信小程序仿淘宝热搜词在搜索框中轮播功能
2020/01/21 Javascript
使用原生JS实现滚轮翻页效果的示例代码
2020/05/31 Javascript
python根据经纬度计算距离示例
2014/02/16 Python
Python中文竖排显示的方法
2015/07/28 Python
Python学生成绩管理系统简洁版
2020/04/05 Python
Python列表切片操作实例总结
2019/02/19 Python
python,Django实现的淘宝客登录功能示例
2019/06/12 Python
Python PIL图片添加字体的例子
2019/08/22 Python
python 带时区的日期格式化操作
2020/10/23 Python
购买原创艺术品:Zatista
2019/11/09 全球购物
护士岗前培训自我评鉴
2014/02/28 职场文书
愚人节活动策划方案
2014/03/11 职场文书
法人代表委托书
2014/04/04 职场文书
关于教师节的广播稿
2014/09/10 职场文书
防汛工作情况汇报
2014/10/28 职场文书
违反工作规定检讨书范文
2014/12/14 职场文书
妇产科护理心得体会
2016/01/22 职场文书
python 如何在 Matplotlib 中绘制垂直线
2021/04/02 Python
python实现自动化群控的步骤
2021/04/11 Python
详解Redis集群搭建的三种方式
2021/05/31 Redis
pandas进行数据输入和输出的方法详解
2022/03/23 Python
Win11右下角图标点了没反应怎么办?Win11点击右下角图标无反应解决方法汇总
2022/07/07 数码科技