关于JavaScript语句后面的分号问题


Posted in Javascript onDecember 07, 2017

JavaScript自动加分号规则,有3条

  1. 当有换行符(包括含有换行符的多行注释),并且下一个token没法跟前面的语法匹配时,会自动补分号。
  2. 当有}时,如果缺少分号,会补分号
  3. 当程序源代码结束时,如果缺少分号,会补分号。 

利用我自己的JS语法分析工具JSinJS(https://github.com/kissjs/JSinJS ),我求出了所有能够出现在语句第一个的JS语法标记 (就是Statement的first集合),他们是:

["debugger", "try", "throw", "switch", "Identifier", "with", "return", "break", "continue", "for", "while", "do", "if", "new", "function", "(", "{", "[", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "this", "!", "~", "-", "+", "--", "++", "typeof", "void", "delete", ";", "var"]

共计35个。 

我又求出了所有可以出现在分号之前的语法标记(即去掉分号以后的last集),他们是

["--", "++", "IdentifierName", "]", ")", "}", "RegularExpressionLiteral", "StringLiteral", "NumericLiteral", "BooleanLiteral", "NullLiteral", "Identifier", "this", "debugger", "return", "break", "continue"]

共计17个。

35*17 = 595种组合,为了方便记忆,以下我分组来讨论语法歧义 。(本来用Excel弄了张表,不过表太大了不好贴出来)

首先,以下语法标记开头的语句是绝对安全的,不会跟不加分号的上一行产生任何歧义:

var if do while for continue break return with switch throw try debugger ;

接下来我们来分组看不加分号导致的语法歧义:

  1. 第一种是++和--两种运算符出现在上一行结尾的情况,下一行以以下开头时,会产生语法歧义: 
  2. function delete void typeof new null true false NumericLiteral StringLiteral RegularExpressionLiteral ( [ { Identifier ++ -- + - ~ ! 
  3. 其中,function和delete是非常常用的statement开头。
  4. 特别是 ++和--单独被断为一行的时候,因为JS的语法规则规定后自增运算不允许中间插入换行,所以++和--会被视为前自增而跟下一行连接在一起。
  5. 第二种是return作为上一行结尾的情况,下一行以以下开头时,会产生语法歧义:
  6. function delete void typeof ( [ { Identifier ++ -- + - ~ !
  7. 同样因为JS语法的规则不允许在return 和后面的值之间插入换行,所以return之后只要有换行符就会视为有分号,这常常会与使用者的期望不符合。
  8. 第三种是下一行以+和-开头的情况,上一行以以下结尾是,会产生语法歧义:
  9. -- ++ IdentifierName ] ) } RegularExpressionLiteral
  10. 因为很少有语句以+或者-开头,所以这种情况不算危险。
  11. 第四种是上一行以break、continue结尾的情况,下一行以Identifier开头时,会产生语法歧义。
  12. 第五种是下一行以(和[开头的情况,上一行以以下结尾是,会产生语法歧义:
  13. -- ++ IdentifierName ] ) } RegularExpressionLiteral StringLiteral NumericLiteral BooleanLiteral NullLiteral Identifier this 
  14. 这种情况非常危险(所以hax的文章中要提出这种情况应该语句前写分号),几乎上一行的所有情况都将导致正常期望之外的结果。
  15. 第六种是,当下一行以RegularExpressionLiteral 开头的情况,上一行的以下结尾,会导致/被理解为除号:
  16. -- ++ IdentifierName ] ) }  RegularExpressionLiteral StringLiteral NumericLiteral BooleanLiteral NullLiteral Identifier this

总结,

  1. 在return、break、continue、后自增、后自减五种语句中,换行符可以完全替代分号的作用。
  2. var if do while for continue break return with switch throw try debugger几种关键字开头的语句,以及空语句,上一行加不加分号影响不大。
  3. 凡表达式语句和函数表达式语句,后面不加分号非常危险,情况极其复杂。
  4. 凡(和[开头的语句,前面不加分号极度危险。

下面在通过实例代码介绍下JavaScript中的分号问题

一般在比较懒的前台程序员中经常会碰到一些莫名其妙的问题。

今天仅讨论一下在JS中经常会碰到一些关于分号的问题。JavaScript这门语言是可以省略分号的,是因为它会换行符后如果缺少分号就会无法编译时它会默认添加上分号,但是在一些特定情况下他是不会默认添加分号的。现在简单介绍一下需要注意的几个地方。

在这种情况时:

var x = 0
[x+1,x+2,x+3].forEach(function(){
console.log(x)
})

这种情况下会导致程序无法正常运行。JavaScript在解析这段代码是并不会在var x = 0后换行。
在写代码时如果以一条语句以 ”(”  ,"[" ,"+" ,"-"  ,"/"  开始时通常在上一条语句不会默认添加分号的。所以在这种情况下尽量保持一下这种写法,在以这些字符开始时在行首添加一个分号,这样可以保证在别人更改上面代码时不加分号也不会影响以下代码运行。

var x = 0
;[x+1,x+2,x+3].forEach(function(){
console.log(x)
})

还有就是在涉及 return   break   continue  这种语句时尽量不要换行

return 
true;
JavaScript会解析为
return; true;
在涉及  ++  和  --  这一系列运算时 在作为表达式的前缀或后缀时在换行是会有一定的问题,如下情况:
var x = 0;
var y = 0;
x
++
y

JavaScript会解析为

x;++y;      而不是    x++;y;

虽然在JavaScript这门语言中  “;”  是可以省略不写的,但是还是建议大家每句代码后都跟上  “;”  养成这种良好的编码习惯,毕竟在大多语言中不带  “;”  的编码适不适用的。

总结

以上所述是小编给大家介绍的JavaScript语句后面的分号问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
jquery实现超简洁的TAB选项卡效果代码
Aug 28 Javascript
JS遍历数组及打印数组实例分析
Jan 21 Javascript
jQuery AjaxUpload 上传图片代码
Feb 02 Javascript
JavaScript快速切换繁体中文和简体中文的方法及网站支持简繁体切换的绝招
Mar 07 Javascript
Javascript必知必会(四)js类型转换
Jun 08 Javascript
完美解决IE不支持Data.parse()的问题
Nov 24 Javascript
深入浅析Vue组件开发
Nov 25 Javascript
node.js的exports、module.exports与ES6的export、export default深入详解
Oct 26 Javascript
微信小程序 生成携带参数的二维码
Oct 23 Javascript
前端开发之便利店收银系统代码
Dec 27 Javascript
JS正则表达式验证端口范围(0-65535)
Jan 06 Javascript
jQuery单页面文字搜索插件jquery.fullsearch.js的使用方法
Feb 04 jQuery
微信小程序获取手机系统信息的方法【附源码下载】
Dec 07 #Javascript
微信小程序实现打开内置地图功能【附源码下载】
Dec 07 #Javascript
js实现关闭网页出现是否离开提示
Dec 07 #Javascript
JavaScrip关于创建常量的知识点
Dec 07 #Javascript
浅谈vue自定义全局组件并通过全局方法 Vue.use() 使用该组件
Dec 07 #Javascript
微信小程序swiper组件用法实例分析【附源码下载】
Dec 07 #Javascript
jQuery实现简单的下拉菜单导航功能示例
Dec 07 #jQuery
You might like
解析php中die(),exit(),return的区别
2013/06/20 PHP
PHP 利用Mail_MimeDecode类提取邮件信息示例
2014/01/26 PHP
PHP面试题之文件目录操作
2015/10/15 PHP
php中this关键字用法分析
2016/12/07 PHP
ThinkPHP实现转换数据库查询结果数据到对应类型的方法
2017/11/16 PHP
PHP自定义错误处理的方法分析
2018/12/19 PHP
基于Jquery实现键盘按键监听
2014/05/11 Javascript
Angularjs编写KindEditor,UEidtor,jQuery指令
2015/01/28 Javascript
jQuery实现DIV层淡入淡出拖动特效的方法
2015/02/13 Javascript
JS+CSS实现的竖向简洁折叠菜单效果代码
2015/10/22 Javascript
轻松学习Javascript闭包函数
2015/12/15 Javascript
Angularjs实现带查找筛选功能的select下拉框示例代码
2016/10/04 Javascript
Ztree新增角色和编辑角色回显问题的解决
2016/10/25 Javascript
详解能在多种前端框架下使用的表格控件
2017/01/11 Javascript
微信小程序实现滑动操作代码
2020/04/23 Javascript
vue路由跳转传递参数的方式总结
2020/05/10 Javascript
[01:50]WODOTA制作 DOTA2中文宣传片《HERO》
2013/04/28 DOTA
[01:26]神话结束了,却也刚刚开始——DOTA2新英雄玛尔斯驾临战场
2019/03/10 DOTA
Python基础中所出现的异常报错总结
2016/11/19 Python
python进程管理工具supervisor的安装与使用教程
2017/09/05 Python
python利用标准库如何获取本地IP示例详解
2017/11/01 Python
pycharm中使用request和Pytest进行接口测试的方法
2020/07/31 Python
CSS3系列教程:背景图片(背景大小和多背景图) 应用说明
2012/12/19 HTML / CSS
浅谈css3中的前缀
2016/07/20 HTML / CSS
谷歌浏览器小字体处理方案即12px以下字体
2013/12/17 HTML / CSS
英国最大的电子零件及配件零售商:Partmaster
2017/04/24 全球购物
BNKR中国官网:带你感受澳洲领先潮流时尚
2018/08/21 全球购物
英国的领先快速时尚零售商:In The Style
2019/03/25 全球购物
EJB的几种类型
2012/08/15 面试题
十八大闭幕感言
2014/01/22 职场文书
高中军训感言1000字
2014/03/01 职场文书
廉洁自律个人总结
2015/02/14 职场文书
学习焦裕禄先进事迹心得体会
2016/01/23 职场文书
纯CSS实现酷炫的霓虹灯效果
2021/04/13 HTML / CSS
如何使用pdb进行Python调试
2021/06/30 Python
ORM模型框架操作mysql数据库的方法
2021/07/25 MySQL