浅析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 相关文章推荐
suggestion开发小结以及对键盘事件的总结(针对中文输入法状态)
Dec 20 Javascript
javascript学习笔记(八) js内置对象
Jun 19 Javascript
获取元素距离浏览器周边的位置的方法getBoundingClientRect
Apr 17 Javascript
javascript 实现子父窗体互相传值的简单实例
Feb 17 Javascript
使用jQuery管理选择结果
Jan 20 Javascript
如何利用JSHint减少JavaScript的错误
Aug 23 Javascript
jQuery动态生成不规则表格(前后端)
Feb 21 Javascript
深入对Vue.js $watch方法的理解
Mar 20 Javascript
解决Jquery下拉框数据动态获取的问题
Jan 25 jQuery
Vue.js 动态为img的src赋值方法
Mar 14 Javascript
小程序实现搜索框功能
Mar 26 Javascript
Vue element-ui父组件控制子组件的表单校验操作
Jul 17 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 中检查或过滤IP地址的实现代码
2011/11/27 PHP
PHP中的魔术方法总结和使用实例
2015/05/11 PHP
jQuery中的.bind()、.live()和.delegate()之间区别分析
2011/06/08 Javascript
jquery $.getJSON()跨域请求
2011/12/21 Javascript
jQuery Mobile的loading对话框显示/隐藏方法分享
2013/11/26 Javascript
Javascript基础教程之break和continue语句
2015/01/18 Javascript
如何实现chrome浏览器关闭页面时弹出“确定要离开此面吗?”
2015/03/05 Javascript
AspNet中使用JQuery上传插件Uploadify详解
2015/05/20 Javascript
js实现仿Discuz文本框弹出层效果
2015/08/13 Javascript
一个php+js实时显示时间问题
2015/10/12 Javascript
jQuery使用中可能被XSS攻击的一些危险环节提醒
2016/05/24 Javascript
浅谈toLowerCase和toLocaleLowerCase的区别
2016/08/15 Javascript
js微信应用场景之微信音乐相册案例分享
2017/08/11 Javascript
Vue2.0 http请求以及loading展示实例
2018/03/06 Javascript
玩转Koa之koa-router原理解析
2018/12/29 Javascript
微信小程序判断用户是否需要再次授权获取个人信息
2019/07/18 Javascript
JS删除对象中某一属性案例详解
2020/09/08 Javascript
[07:59]2014DOTA2叨叨刀塔 林熊猫称被邀请赛现场盛况震撼
2014/07/21 DOTA
Python 初始化多维数组代码
2008/09/06 Python
Python采用raw_input读取输入值的方法
2014/08/18 Python
如何解决django-celery启动后迅速关闭
2019/10/16 Python
浅谈python3 构造函数和析构函数
2020/03/12 Python
pytorch下的unsqueeze和squeeze的用法说明
2021/02/06 Python
基于CSS3实现图片模糊过滤效果
2015/11/19 HTML / CSS
amazeui模态框弹出后立马消失并刷新页面
2020/08/19 HTML / CSS
Daniel Wellington官方海外旗舰店:丹尼尔惠灵顿DW手表
2018/02/22 全球购物
Java里面Pass by value和Pass by Reference是什么意思
2016/05/02 面试题
环境科学专业研究生求职信
2013/10/02 职场文书
集团公司人力资源部岗位职责
2014/01/03 职场文书
保护环境倡议书100字
2014/05/19 职场文书
我的中国梦口号
2014/06/16 职场文书
525心理活动总结
2014/07/04 职场文书
党员学习中共十八大思想报告
2014/09/12 职场文书
思想政治表现评语
2015/01/04 职场文书
联谊会开场白
2015/06/01 职场文书
闪闪红星观后感
2015/06/08 职场文书