JavaScript到底应不应该加分号?JavaScript自动插入分号规则详解
JavaScript 提供了 automatic semicolon insertion (ASI)自动插入分号规则,在不加分号的情况下,会自动补充分号来分隔不同语句。
导致在继左大括号换行、tab 和 space 圣战后,前端又出现了一场战争。
并且随着那个男人加入这场讨论之后,关于是否应该加分号的讨论更是激烈了。

ASI 自动插入分号规则
在决定是否添加分号之前,我们先来了解一下编译器到底在哪些情况下会自动插入分号,哪些情况必须手动添加分号。
会自动添加分号的情况
1.遇到换行符,但是两句代码连接是无效代码
// 代码
42
'hello'
// `42 'hello'`连接在一起是无效语句,所以会自动在之间插入分号
42;'hello'
// 直接明确的写法
42;"hello"
// 代码
let a = 10, b = 5
a
-
b
// a - b 为有效代码,所以三者之间不会自动加分号
a = 1; b = 2;
// 直接明确的写法
a - b
2.遇到换行符,但是两句代码之间不允许有换行符
// 代码
foo
++
bar
++
baz
// foo 和 ++ 符合规则1,但是不符合 no LineTerminator here规则,所以会添加分号
foo;
++bar;
++baz;
在 JS 标准中,有个 no LineTerminator here 的规则,规定哪些语法不能加入换行符,如果开发者加了换行符,则 JS 编译器会无法识别并加入分号。
- 带标签的
continue语句,不能continue后插入换行; - 带标签的
break语句,不能在break后面插入换行; return后面不能插入换行;- 后自增、后自减运算符前不能插入换行;
throw和Exception之间不能插入换行;async关键字,后面不能插入换行;- 箭头函数的箭头前,不能插入换行;
yield之后,不能插入换行。
3.Restricted productions
如果这些标签后,空一行书写其它语句,则会自动在这些标签后添加分号:
++or--returnbreakcontinue- ES6
yield、async等 - 反引号`
// return 后空一行再书写语句,则会自动在 return 后加分号
return
{
a: 1
}
// 这是正确写法
return {
a: 1
}
其它标签类似。
如果手动在这些标签后加上分号,同样也是错误的,比如:
// 空一行再写 a,会自动在 ++ 后添加分号
++
a
// 就算手动添加,和上面结果一样是错误的
++;
a;
所以针对 Restricted productions ,无论让编译器自动添加分号,还是自己手动加上分号,都是错误的,都应该去避免去换行,避免写这种写法。
必须手动加分号的情况
以下面这些标签开头的命令,必须在前面加分号,和前面一个语句分隔:
+和-:语句以 + 或者 - 开头/: 语句以正则表达式开头(: 语句以自执行函数开头[: 语句以数组开头
举例说明:
// 错误
a = b
+a
// 正确
a = b
;+a
// 错误
a = b
/something/.test(a)
// 正确
a = b
;/something/.test(a)
// 错误
a = b
(function () {})()
// 正确
a = b
;(function() {})()
// 错误
a = b
[1, 2, 3].forEach()
// 正确
a = b
;[1, 2, 3].forEach()
上面的情况,如果第二行代码不手动添加分号的话,两行代码会合并在一起导致结果错误或者报错。
上面几种情况中,只有自执行函数和数组开头会在极少情况下遇到,记住这两个前面要手动加上分号即可。
就算是习惯加分号的朋友,但仍然要注意下面的情况:
// 不需要结尾添加分号
if () {
}
// 不需要结尾添加分号
for () {
}
// 不需要结尾添加分号
while () {
}
// 需要在结尾添加分号
var a = function () {
};
// 需要在结尾添加分号
var a = {
prop: value
};
// 报错
[1, 2, 3].forEach();
即便习惯写分号的朋友,也很少有人在 if 、for、while 等语句 } 后写分号,但是如果使用赋值的形式传递,则一定要注意在 } 把分号添加上,以避免后面语句出现自执行和数组开头的语句。
推荐遇到自执行和数组开头的,直接前面加上分号就完事了。
总结
是否添加和是否手动加是两回事,我们可以用 eslint、Prettier 等工具自动生成或者删除分号,是否手动加可以看个人喜好,最终代码内可以根据项目要求用工具生成。
但都要注意必须添加分号的几种情况。
参考文章
- Hacking Semicolons
- What are the rules for JavaScript's automatic semicolon insertion (ASI)? - Stack Overflow
JavaScript到底应不应该加分号?JavaScript自动插入分号规则详解的更多相关文章
- 防止 JavaScript 自动插入分号
JavaScript语言有一个机制:在解析时,能够在一句话后面自动插入一个分号,用来修改语句末尾遗漏的分号分隔符. 然而,由于这个自动插入的分号与JavaScript语言的另一个机制发生了冲突,即所有 ...
- js 自动插入分号
先来看一个例子: function get(){ return { a:1 } } var r=get(); console.log(r); 似乎r的值应该是{a:1},然而运行结果却是undefin ...
- iOS开发——加载、滑动翻阅大量图片解决方案详解
加载.滑动翻阅大量图片解决方案详解 今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...
- SQL Prompt 格式化SQL会自动插入分号的问题
一.问题 安装新版SQL Prompt,格式化SQL都会自动在SQL末端插入分号 格式化前 格式化后 二.解决方法 选择SQL Prompt下的Options... 选择左侧的Format下Style ...
- Javascript面向对象三大特性(封装性、继承性、多态性)详解及创建对象的各种方法
Javascript基于对象的三大特征和C++,Java面向对象的三大特征一样,都是封装(encapsulation).继承(inheritance )和多态(polymorphism ).只不过实现 ...
- JavaScript 对象、DOM对象、jquery对象的区别、转换详解
一.JavaScript 对象 JavaScript 提供多个内建对象,比如 String.Date.Array 等等. 对象只是带有属性和方法的特殊数据类型. 访问对象的属性: [javascrip ...
- Android 平滑图片加载和缓存库 Glide 使用详解
在图片加载库烂大街的今天,选择一个适合自己使用的图片加载库已经成为了每一个Android开发者的必经之路.现在市面上知名的图片加载库有UIL,Picasso,Volley ImageLoader,Fr ...
- php中自动加载类_autoload()和spl_autoload_register()实例详解
一._autoload 自动加载类:当我们实例化一个未定义的类时,就会触此函数.到了php7.1以后版本不支持此函数好像抛弃了 新建一个类文件名字自己随便去:news类在auto.php文件里面去实例 ...
- Spring Cloud Alibaba基础教程:Nacos配置的加载规则详解
前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式(Res ...
- [Aaronyang] 写给自己的WPF4.5 笔记6[三巴掌-大数据加载与WPF4.5 验证体系详解 2/3]
我要做回自己--Aaronyang的博客(www.ayjs.net) 博客摘要: Virtualizing虚拟化DEMO 和 大数据加载的思路及相关知识 WPF数据提供者的使用ObjectDataPr ...
随机推荐
- STM32外设:串行通信 USART、I2C、SPI
USART:Universal Synchronous Asynchronous Receiver Transmitter 通用同步异步接收发送器 UART:异步中断 主要功能:接收指定长度的帧 数据 ...
- serdes 复制时钟
serdes复制时钟一般指的是,将rx lane的CDR 恢复时钟发送给TX/PLL, 这样rx和tx的时钟频偏就一致,在远端环回时经常用到.RX,TX时钟同频后环回数据就可以畅通发出去,否则RX/T ...
- SpringBoot CORS 跨域请求解决方案之配置过滤器
方式一:@CrossOrigin 方式二: @Configuration public class CorsConfig implements WebMvcConfigurer { @Override ...
- ElasticSearch之Create index API
创建指定名称的index. 命令样例如下: curl -X PUT "https://localhost:9200/testindex_002?pretty" -H 'Conten ...
- ElasticSearch之cat transforms API
命令样例如下: curl -X GET "https://localhost:9200/_cat/transforms?v=true&format=json" --cace ...
- ElasticSearch之cat data frame analytics API
命令样例如下: curl -X GET "https://localhost:9200/_cat/ml/data_frame/analytics?v=true&pretty" ...
- 在Linux上部署.net Core 步骤以及遇到的一些问题
Linux安装部署手册 一.安装.NET Core SDK centos 7 系统命令为: sudo rpm -Uvh https://packages.microsoft.com/config/ce ...
- 从0开始学微信逆向开发(android版)——第一栏
首先给大家普及一下啥叫微信逆向开发,以及微信逆向开发能做什么: 场景1:小明是做微商的,他每天需要加很多很多的好友.然后他会通过微信的各种渠道去添加好友,比如(附近的人.摇一摇.漂流瓶.手机号搜索等) ...
- struts2 Filter中无法转发请求
struts2 Filter中无法转发请求 项目升级struts2版本为最新以修复漏洞,由于一些历史原因,部分访问在升级后访问404,直接对历史代码改造代价太大. 于是使用拦截器对其转发.重定向,但是 ...
- 创建傀儡进程svchost.exe并注入DLL文件(Shellcode)
本文主要利用 SetThreadContext 修改进程中的线程上下文来实现Dll注入(ShellCode). 实现原理 首先,使用 CreateProcess 函数创建svchost.exe进程,并 ...