浅析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 纠正 cleanWhitespace函数
Mar 11 Javascript
浅谈javascript语法和定时函数
May 03 Javascript
coffeescript使用的方式汇总
Aug 05 Javascript
javascript实现在指定元素中垂直水平居中
Sep 13 Javascript
Node.js通过身份证号验证年龄、出生日期与性别方法示例
Mar 09 Javascript
JQ图片文件上传之前预览功能的简单实例(分享)
Nov 12 Javascript
微信小程序scroll-view组件实现滚动动画
Jan 31 Javascript
vue基于两个计算属性实现选中和全选功能示例
Feb 08 Javascript
Vue项目路由刷新的实现代码
Apr 17 Javascript
小程序关于请求同步的总结
May 05 Javascript
javascript的delete运算符知识点总结
Nov 19 Javascript
Vue组件间的通信pubsub-js实现步骤解析
Mar 11 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 UTF8编码内的繁简转换类
2009/07/20 PHP
PHP和.net中des加解密的实现方法
2013/02/27 PHP
php使用array_search函数实现数组查找的方法
2015/06/12 PHP
PHP基于SMTP协议实现邮件发送实例代码
2017/04/27 PHP
利用Laravel事件系统如何实现登录日志的记录详解
2017/05/20 PHP
PHP基于curl实现模拟微信浏览器打开微信链接的方法示例
2019/02/15 PHP
PHP实时统计中文字数和区别
2019/02/28 PHP
CI框架简单分页类用法示例
2020/06/06 PHP
Extjs TimeField 显示正常时间格式的代码
2011/06/28 Javascript
javascript代码编写需要注意的7个小细节小结
2011/09/21 Javascript
js实现适用于素材网站的黑色多级菜单导航条效果
2015/08/24 Javascript
Bootstrap精简教程
2015/11/27 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
2016/09/06 Javascript
JS判断输入的字符串是否是数字的方法(正则表达式)
2016/11/29 Javascript
JavaScript模拟实现封装的三种方式及写法区别
2017/10/27 Javascript
create-react-app构建项目慢的解决方法
2018/03/14 Javascript
react脚手架如何配置less和ant按需加载的方法步骤
2018/11/28 Javascript
uni-app 支持多端第三方地图定位的方法
2020/01/03 Javascript
[47:50]Secret vs VP 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/20 DOTA
python中文件变化监控示例(watchdog)
2017/10/16 Python
python tools实现视频的每一帧提取并保存
2020/03/20 Python
Selenium+Python 自动化操控登录界面实例(有简单验证码图片校验)
2019/06/28 Python
python opencv鼠标事件实现画框圈定目标获取坐标信息
2020/04/18 Python
Python3.7+tkinter实现查询界面功能
2019/12/24 Python
通过python连接Linux命令行代码实例
2020/02/18 Python
解决pycharm中opencv-python导入cv2后无法自动补全的问题(不用作任何文件上的修改)
2020/03/05 Python
Python调用SMTP服务自动发送Email的实现步骤
2021/02/07 Python
英国高街品牌:Miss Selfridge(塞尔弗里奇小姐)
2016/09/21 全球购物
Expedia英国:全球最大的在线旅游公司
2017/09/07 全球购物
英国足球店:UK Soccer Shop
2017/11/19 全球购物
应届生人事助理求职信
2013/11/09 职场文书
大学毕业生的自我鉴定
2013/11/30 职场文书
机电系毕业生求职信
2014/07/11 职场文书
教师师德师风自我剖析材料
2014/09/29 职场文书
校长新学期寄语2016
2015/12/04 职场文书
sql server 累计求和实现代码
2022/02/28 SQL Server