JS的分号可以省掉吗?
摘要: JavaScript语言从设计之初就是考虑带分号的,使用不带分号的编码规则就要小心点啦。
背景
最近在项目中开始使用新的编码规范,一开始ESLint报一大堆错误,改得我想砸键盘,花了好些时间才适应,下面列出一些代表性的规则:
- 只能使用单引号
- 函数定义的圆括号和左大括号之间一定要有空格:
function(args) { .. } - import语句在大括号之后一定要有空格:
import { fa, fb } from moduleC - 不用分号!!!
起因
早上在实现一个功能的时候,写了一个map函数来复用部分代码。程序运行起来后,没有执行结果,而且没有报错。通过console.log打印数据发现,整个程序执行到map前面就再也不往下走了,很奇怪。因为没有报错信息,无法推测具体原因。于是,我将其抽象成非常简单的代码来排查。如下所示:
console.log("hello, fundebug")
[1, 2, 3].map(i=>console.log(i))
然后执行看看结果如何:

在项目中没有报错,单独将这段代码拿出来在浏览器控制台下执行却报错了!
这么简单的代码为什么会出错呢?第一反应就是JS引擎将代码生成语法树的时候,可能解析不正确。于是,我在第一行末尾加分号测试。
console.log("hello, fundebug");
[1, 2, 3].map(i=>console.log(i))
程序正确执行了:

这让我更加犯难,如果不加分号会导致程序出错,那么为什么还会推崇这样的编码规范呢?
在网络上搜索JavaScript关于分号的BUG,发现有非常多关于要不要使用分号的讨论。
大宗师Douglas Crockford表示要正确使用分号
引用minhan在扯不完的 JS 分号问题文中的论述:
JSON、JSLint、JSMin和ADSafe 的创造者、ECMA JavaScript 2.0 标准化委员会委员、被JavaScript之父Brendan Eich称为JavaScript的大宗师、名著《JavaScript: The Good Parts》(中文版《JavaScript语言精粹》)的作者Douglas Crockford直接怼之: 这代码真尼玛的疯狂傻X,我是不会为了这傻X的案例而去降低JSMin的级数; TC39正在考虑将『!』号作为中缀运算符使用,这个代码不久将来就运行不了。赶紧修复吧,学学怎么正确地使用分号。『!』号并不语句的分隔号,『;』才是。
JSMin处理如下代码后无法正确执行:
clearMenus()
!isActive && $parent.toggleClass('open')
自动分号插入机制
JavaScript有着自动分号插入的机制(Automatic Semicolon Insertion),简称ASI。这是一个辅助性的功能,然后有一些情况要注意:
如果你这样写代码:
return
a + b
那么自动分号插入后会这样:
return;
a + b;
更可能导致隐含BUG的状况是:
a = b + c
(d + e).print()
他不会自动插入分号,因为第二行一括号开始,会被误认为是函数。
a = b + c(d + e).print();
所以,我刚刚的的代码在自动插入分号后,应该是这样:
console.log("hello fundebug")[1,2,3].map(i=>console.log(i))
那么这样看来,用分号才是最安全的做法咯!
如果你不想用分号,又怕出问题,v2ex上有位童鞋给出了一个速记方案:
如果你写 JS 代码不喜欢带分号,而又搞不清什么时候必须加分号,可以这么做:在以 "("、"[" 、"/"、"+"、"-" 开头的语句前面都加上一个分号。
我最终的解法是先声明一个变量来指向这个数组,这样就可以避免以[开头,又不使用分号:
let indexArray = [1, 2, 3]
indexArray.map(i=>console.log(i))
关于Fundebug
Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了6亿+错误事件,得到了Google、360、金山软件等众多知名用户的认可。欢迎免费试用!
转载时请注明作者 Fundebug以及本文地址:
https://blog.fundebug.com/ 2018/09/18/js-semicolon-bug/
JS的分号可以省掉吗?的更多相关文章
- 如果您想省略JS里的分号,了解一下JS的分号插入原理吧
仅在}之前.一个或多个换行之后和程序输入的结尾被插入 也就是说你只能在一行.一个代码块和一段程序结束的地方省略分号. 也就是说你可以写如下代码 function square(x) { var n = ...
- Js中分号使用总结
作者:尤雨溪链接:https://www.zhihu.com/question/20298345/answer/49551142来源:知乎著作权归作者所有,转载请联系作者获得授权. 没有应该不应该,只 ...
- 什么是js和js的基本语法
时间:2016年12月15日 先讲讲基础语法: 大部分是来操作表单: js动态效果和数据交互(ajax?) js也有自己的API js大部分的DOM操作都是针对input的. 案例学习,对注册页面的简 ...
- 《JS权威指南学习总结--第二章词法结构》
第二章词法结构 内容要点: 一.注释 1. //表示单行注释 2. /*这里是一段注释*/ 3.一般编辑器里加注释是:选中要加注释的语句,按 ctrl+/ 二.直接量 所谓直接量,就是程序中直接使用的 ...
- 从零开始的JS生活(一)——JS简介、变量及基本结构
本K在经过三个静态站制作的狂风暴雨之后,终于开始了JavaScript的学习.作为一只从来没有正儿八经接受过计算机语言的小白,居然能够跟上浩哥的课程进度,我的内心都被我的才智震惊到了,果然本K是天生丽 ...
- JS相关重点知识 (概况)
1.value和innerHTML没有联系,只是value是表单的一个特有属性,而innerHTML是通用的. 2.当从外部引入js文件时,该外部文件里面可以有多个方法, html页面中的oncl ...
- auto semicolon insertion 自动分号补齐的坑
今天发现js自动分号补齐的坑,来看如下两段代码: function Hello(){ return { name: ’JavaScript’ }; } alert(Hello()); //输出unde ...
- js面试题总结
1.typeof和Object.prototype.toString typeof是js里面判断变量类型的一种方法,但这种方法没有Object.prototype.toString准确,前者有6种判断 ...
- js上 二.JavaScript基本语法
1.JavaScript词法结构 所谓词法结构是指一套基础性规则,用来描述如何使用这门语言来编写程序,包括如下几项: ü 字符集unicode ü 区分大小写 (true和TRUE) ü 忽略空白字符 ...
随机推荐
- undo空间满的处理方法(含undo的学习与相关解释)
1.查看数据库当前实例使用的是哪个UNDO表空间: show parameter undo_tablespace 2.查看UNDO表空间对应的数据文件和大小 pages col file_name f ...
- 有关C++模板inline的高性能在lambda与function的体现
前两天在群里跟人讨论到写库时对于lambda和function的取舍,跑了写测试查了些资料后基本得出结论: 如果没有自由变量的情况下,一般不要用function. 如果有自由变量的话,C++中的lam ...
- 利用Go2Shell 实现 Mac Finder 直接shell端打开当前文件夹
Finder 窗口 ,点击下图所示的按钮(红色框内),即可打开Shell Terminal. 打开后,如图 用法 安装go2shell后,打开finder的application文件夹,找到go2sh ...
- git 命令(基础篇)的本质理解
主要命令 1. 提交,git commit 本质:创建一个节点(node),标志了当前位置(node)与以前的node存在不同之处,如下图中的 c0 <-- c1 <-- c2 等等 图中 ...
- 4.ASP.NET MVC 5.0 视图之模型绑定
大家好,这篇文章,我将向大家介绍ASP.NET MVC的模型视图绑定,ASP.MVC的模型绑定分为两种:一种是动态绑定[Dynamic Binding];还有一种就是强类型绑定[Strongly ty ...
- 【Selenium专题】鼠标键盘事件
引用包来自selenium-java-2.23.1.jar 调用以下代码时,需要引入actions类,以java为例: import org.openqa.selenium.interactions. ...
- 2019-4-25 html学习笔记
一.概念 文本 用于储存和记录文字信息的载体 html 超文本标记语言(本质就是给文本增加语义 如<h1></h1>就是给文字添加一级标题的语义) 注:互联网三大基石 有 ...
- jdk8新特性---list.stream
项目中用到了该api ,记录下来 具有get set 构造方法的实体类 开始使用: 结果为: 更多可以参考: https://blog.csdn.net/justloveyou_/article/de ...
- eclipse——JDK安装与环境变量配置步骤
第一次接触eclipse的时候,让我自己安装jdk和配置环境变量,我是懵逼的,后来百度到找到了一个比较详细的引导,本人测试没问题,截图按步骤如下: JDK安装 步骤1: 步骤2: 配置环境变量 步 ...
- 自定义线程池reject策略
import java.util.Date;import java.util.concurrent.ArrayBlockingQueue;import java.util.concurrent.Rej ...