关于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 相关文章推荐
js禁止document element对象选中文本实现代码
Mar 21 Javascript
JavaScript实现找出字符串中第一个不重复的字符
Sep 03 Javascript
Jquery实现弹性滑块滑动选择数值插件
Aug 08 Javascript
JavaScript+CSS无限极分类效果完整实现方法
Dec 22 Javascript
基于JS实现数字+字母+中文的混合排序方法
Jun 06 Javascript
Jquery Easyui进度条组件Progress使用详解(8)
Mar 26 Javascript
JavaScript实现弹窗效果代码分析
Mar 09 Javascript
easyui-datagrid特殊字符不能显示的处理方法
Apr 12 Javascript
使用DataTable插件实现异步加载数据
Nov 19 Javascript
javaScript手机号码校验工具类PhoneUtils详解
Dec 08 Javascript
微信小程序用户盒子、宫格列表的实现
Jul 01 Javascript
在Vue中使用Echarts可视化库的完整步骤记录
Nov 18 Vue.js
微信小程序获取手机系统信息的方法【附源码下载】
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
用Apache反向代理设置对外的WWW和文件服务器
2006/10/09 PHP
UCenter 批量添加用户的php代码
2012/07/17 PHP
PHP入门教程之会话控制技巧(cookie与session)
2016/09/11 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
js中根据字数截取字符串,不能截断url
2012/01/12 Javascript
jquery实现鼠标点击后展开列表内容的导航栏效果
2015/09/14 Javascript
Javascript生成全局唯一标识符(GUID,UUID)的方法
2016/02/27 Javascript
Jquery ajax请求导出Excel表格的实现代码
2016/06/08 Javascript
AngularJS表单提交实例详解
2017/02/18 Javascript
js实现常见的工具条效果
2017/03/02 Javascript
Bootstrap Table使用整理(三)
2017/06/09 Javascript
weui框架实现上传、预览和删除图片功能代码
2017/08/24 Javascript
详解Vue路由钩子及应用场景(小结)
2017/11/07 Javascript
浅谈vuex 闲置状态重置方案
2018/01/04 Javascript
AngularJS select加载数据选中默认值的方法
2018/02/28 Javascript
Vue自定义弹窗指令的实现代码
2018/08/13 Javascript
Vue高版本中一些新特性的使用详解
2018/09/25 Javascript
vue+echarts实现可拖动节点的折线图(支持拖动方向和上下限的设置)
2019/04/12 Javascript
微信小程序中为什么使用var that=this
2019/08/27 Javascript
解决在Vue中使用axios用form表单出现的问题
2019/10/30 Javascript
详解JavaScript数据类型和判断方法
2020/09/04 Javascript
[02:19]2014DOTA2国际邀请赛 专访820少年们一起去追梦吧
2014/07/14 DOTA
pycharm 使用心得(三)Hello world!
2014/06/05 Python
python修改操作系统时间的方法
2015/05/18 Python
Django中URL的参数传递的实现
2019/08/04 Python
什么是Python中的顺序表
2020/06/02 Python
学习Python爬虫的几点建议
2020/08/05 Python
Python使用lambda抛出异常实现方法解析
2020/08/20 Python
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
YSL圣罗兰美妆俄罗斯官网:Yves Saint Lauret RU
2020/09/23 全球购物
护理不良事件检讨书
2014/02/06 职场文书
网站创业计划书
2014/04/30 职场文书
国家领导干部党的群众路线教育实践活动批评与自我批评材料
2014/09/23 职场文书
群众路线教育实践活动整改方案(个人版)
2014/10/25 职场文书
2016年教师节感言
2015/12/09 职场文书
详解在SQLPlus中实现上下键翻查历史命令的功能
2022/03/18 SQL Server