浅析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入门·图片对象(无刷新变换图片)\滚动图像
Oct 01 Javascript
禁止js文件缓存的代码
Apr 09 Javascript
jquery 如何动态添加、删除class样式方法介绍
Nov 07 Javascript
js中for in的用法示例解析
Dec 25 Javascript
js无刷新操作table的行和列
Mar 27 Javascript
纯javascript实现图片延时加载方法
Aug 21 Javascript
剖析Node.js异步编程中的回调与代码设计模式
Feb 16 Javascript
JS触发服务器控件的单击事件(详解)
Aug 06 Javascript
加载 vue 远程代码的组件实例详解
Nov 20 Javascript
解决layer 关闭当前弹窗 关闭遮罩层 input值获取不到的问题
Sep 25 Javascript
vue-cli打包后本地运行dist文件中的index.html操作
Aug 12 Javascript
Node.js 中如何收集和解析命令行参数
Jan 08 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
SESSION信息保存在哪个文件目录下以及能够用来保存什么类型的数据
2012/06/17 PHP
PHP实现的多维数组去重操作示例
2018/07/21 PHP
php服务器的系统详解
2019/10/12 PHP
js String对象中常用方法小结(字符串操作)
2012/01/27 Javascript
简单谈谈javascript中的变量、作用域和内存问题
2015/08/30 Javascript
javascript设置页面背景色及背景图片的方法
2015/12/29 Javascript
jquery实现简单的全选和反选功能
2016/01/02 Javascript
仅30行代码实现Javascript中的MVC
2016/02/15 Javascript
详解JavaScript正则表达式之分组匹配及反向引用
2016/03/09 Javascript
jquery弹出遮掩层效果【附实例代码】
2016/04/28 Javascript
Bootstrap框架安装使用详解
2017/01/21 Javascript
javascript history对象详解
2017/02/09 Javascript
vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理
2017/03/06 Javascript
js中的面向对象入门
2017/03/06 Javascript
全面解析vue中的数据双向绑定
2017/05/10 Javascript
深入掌握 react的 setState的工作机制
2017/09/27 Javascript
浅谈Vue内置component组件的应用场景
2018/03/27 Javascript
原生javascript AJAX 三级联动的实现代码
2018/05/04 Javascript
对layui中表单元素的使用详解
2018/08/15 Javascript
解析原来浏览器原生支持JS Base64编码解码
2019/08/12 Javascript
Vue 自定义指令实现一键 Copy功能
2019/09/16 Javascript
layui 实现加载动画以及非真实加载进度的方法
2019/09/23 Javascript
在vue中使用inheritAttrs实现组件的扩展性介绍
2020/12/07 Vue.js
玩转python爬虫之爬取糗事百科段子
2016/02/17 Python
python anaconda 安装 环境变量 升级 以及特殊库安装的方法
2017/06/21 Python
Python wxPython库消息对话框MessageDialog用法示例
2018/09/03 Python
基于python实现把图片转换成素描
2019/11/13 Python
Python3基于print打印带颜色字符串
2020/07/06 Python
Pycharm中使用git进行合作开发的教程详解
2020/11/17 Python
让IE9以下版本的浏览器兼容HTML5的方法
2014/03/12 HTML / CSS
HTML5新标签兼容——> 的两种方法
2018/09/12 HTML / CSS
人力资源管理专业毕业生自我评价
2013/09/21 职场文书
法学毕业生自我鉴定
2014/01/31 职场文书
庆元旦广播稿
2014/02/10 职场文书
旅游饭店管理专业自荐书
2014/06/28 职场文书
导航工程专业自荐信
2014/09/02 职场文书