浅析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 相关文章推荐
用jscript实现列出安装的软件列表
Jun 18 Javascript
Firefox和IE浏览器兼容JS脚本写法小结
Jul 07 Javascript
javascript不同页面传值的改进版
Sep 30 Javascript
jquery 经典动画菜单效果代码
Jan 26 Javascript
jquery+ajax请求且带返回值的代码
Aug 12 Javascript
JavaScript原生xmlHttp与jquery的ajax方法json数据格式实例
Dec 04 Javascript
JavaScript使用atan2来绘制箭头和曲线的实例
Sep 14 Javascript
Vue精简版风格概述
Jan 30 Javascript
详解React项目中碰到的IE问题
Mar 14 Javascript
优雅的将ElementUI表格变身成树形表格的方法步骤
Apr 11 Javascript
JavaScript TAB栏切换效果的示例
Nov 05 Javascript
vue如何清除浏览器历史栈
May 25 Vue.js
完美解决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 preg_replace替换实例讲解
2013/11/04 PHP
php 生成自动创建文件夹并上传文件的示例代码
2014/03/07 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
2015/05/12 PHP
PHP对称加密算法(DES/AES)类的实现代码
2017/11/14 PHP
jquery ajax abort()的使用方法
2010/10/28 Javascript
jquery 操作日期、星期、元素的追加的实现代码
2012/02/07 Javascript
js操纵跨frame的三级联动select下拉选项实例介绍
2013/05/19 Javascript
AngularJS动态加载模块和依赖的方法分析
2016/11/08 Javascript
JS实现页面中所有img对象添加onclick事件及新窗口查看图片的方法
2016/12/27 Javascript
bootstrap实现二级下拉菜单效果
2017/11/23 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
详解小程序之简单登录注册表单验证
2019/05/13 Javascript
基于iview-admin实现动态路由的示例代码
2019/10/02 Javascript
[01:02]DOTA2上海特锦赛SHOWOPEN
2016/03/25 DOTA
Python简单删除目录下文件以及文件夹的方法
2015/05/27 Python
以视频爬取实例讲解Python爬虫神器Beautiful Soup用法
2016/01/20 Python
Python中int()函数的用法浅析
2017/10/17 Python
python抓取京东小米8手机配置信息
2018/11/13 Python
django小技巧之html模板中调用对象属性或对象的方法
2018/11/30 Python
在Python中,不用while和for循环遍历列表的实例
2019/02/20 Python
Python爬虫之urllib基础用法教程
2019/10/12 Python
浅谈Python类中的self到底是干啥的
2019/11/11 Python
python3 动态模块导入与全局变量使用实例
2019/12/22 Python
Pytorch高阶OP操作where,gather原理
2020/04/30 Python
python实现录制全屏和选择区域录屏功能
2021/02/05 Python
HTML5 canvas基本绘图之图形变换
2016/06/27 HTML / CSS
HTML5中外部浏览器唤起微信分享功能的代码
2020/09/15 HTML / CSS
北美三大旅游网站之一:Travelocity
2017/08/12 全球购物
P D PAOLA意大利官网:西班牙著名的珠宝首饰品牌
2019/09/24 全球购物
药学专业个人自我评价
2013/11/11 职场文书
项目总经理岗位职责
2014/02/14 职场文书
抽奖活动主持词
2014/03/31 职场文书
危爆物品安全大检查大整治工作方案
2014/05/03 职场文书
总经理人事任命书
2014/06/05 职场文书
MBA推荐信怎么写
2015/03/25 职场文书
tomcat的catalina.out日志按自定义时间格式进行分割的操作方法
2022/04/02 Servers