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--
return
break
continue
- 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 ...
随机推荐
- 公司要做大数据可视化看板,除了EXCEL以外有没有好用的软件可以用
当企业需要进行大数据可视化看板的设计和开发时,除了Excel,还有许多其他强大且适合大数据可视化的软件工具.以下是几种常用的好用软件,以及它们的特点和优势,供您参考. 一.Datainside 特点和 ...
- C语言数组实现扫雷
C语言数组->实现扫雷 包含头文件 #include <stdio.h> #include <stdlib.h> //用于生成随机数 #include <time. ...
- [ABC246G] Game on Tree 3
Problem Statement There is a rooted tree with $N$ vertices, Vertex $1$ being the root. For each $i = ...
- 记录一下Stream流的一个坑
List<String> list = new ArrayList<>(); boolean a = list.stream().anyMatch("a": ...
- Charles对Android手机Https请求的抓包
Charles对Android手机Https请求的抓包 • 前情提要: 本文只是对android手机进行抓包的描述,由于android手机系统原因,android7.0系统及以上需要在app中配置证书 ...
- CentOS7部署后优化配置
1.安装必要的组件.升级 yum -y install wget vim cd /etc/yum.repos.d/ rm -rf /etc/yum.repos.d/*.repo wget http:/ ...
- 未能加载文件或程序集“*****.dll”或它的某一个依赖项。找到的程序集清单定义与程序集引用不匹配。(异常来自HRESULT:0x80131040)
问题描述: 未能加载文件或程序集"*****.dll"或它的某一个依赖项.找到的程序集清单定义与程序集引用不匹配.(异常来自HRESULT:0x80131040) 解决方法: 1. ...
- 请注意,你的 Pulsar 集群可能有删除数据的风险
在上一篇 Pulsar3.0新功能介绍中提到,在升级到 3.0 的过程中碰到一个致命的问题,就是升级之后 topic 被删除了. 正好最近社区也补充了相关细节,本次也接着这个机会再次复盘一下,毕竟这是 ...
- Spring Boot入坑-3-Maven简介
概述 Maven是一个自动化构建工具 能够将支持Maven项目的依赖包从远程仓库拉取到本地仓库,并进行依赖管理 项目中通过pom.xml来描述项目,对项目依赖进行管理与配置 给项目提供编译.打包.安装 ...
- Asp .Net Core 系列:基于 Swashbuckle.AspNetCore 包 集成 Swagger
什么是 Swagger? Swagger 是一个规范和完整的框架,用于生成.描述.调用和可视化 RESTful 风格的 Web 服务.它提供了一种规范的方式来定义.构建和文档化 RESTful Web ...