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 编译器会无法识别并加入分号。

  1. 带标签的continue语句,不能continue后插入换行;
  2. 带标签的break语句,不能在break后面插入换行;
  3. return后面不能插入换行;
  4. 后自增、后自减运算符前不能插入换行;
  5. throwException之间不能插入换行;
  6. async关键字,后面不能插入换行;
  7. 箭头函数的箭头前,不能插入换行;
  8. yield之后,不能插入换行。

3.Restricted productions

如果这些标签后,空一行书写其它语句,则会自动在这些标签后添加分号:

  • ++ or --
  • return
  • break
  • continue
  • ES6 yieldasync
  • 反引号`
// 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();

即便习惯写分号的朋友,也很少有人在 ifforwhile 等语句 } 后写分号,但是如果使用赋值的形式传递,则一定要注意在 } 把分号添加上,以避免后面语句出现自执行和数组开头的语句。

推荐遇到自执行和数组开头的,直接前面加上分号就完事了。

总结

是否添加和是否手动加是两回事,我们可以用 eslint、Prettier 等工具自动生成或者删除分号,是否手动加可以看个人喜好,最终代码内可以根据项目要求用工具生成。

但都要注意必须添加分号的几种情况。

参考文章

JavaScript到底应不应该加分号?JavaScript自动插入分号规则详解的更多相关文章

  1. 防止 JavaScript 自动插入分号

    JavaScript语言有一个机制:在解析时,能够在一句话后面自动插入一个分号,用来修改语句末尾遗漏的分号分隔符. 然而,由于这个自动插入的分号与JavaScript语言的另一个机制发生了冲突,即所有 ...

  2. js 自动插入分号

    先来看一个例子: function get(){ return { a:1 } } var r=get(); console.log(r); 似乎r的值应该是{a:1},然而运行结果却是undefin ...

  3. iOS开发——加载、滑动翻阅大量图片解决方案详解

    加载.滑动翻阅大量图片解决方案详解     今天分享一下私人相册中,读取加载.滑动翻阅大量图片解决方案,我想强调的是,编程思想无关乎平台限制. 我要详细说一下,在缩略图界面点击任意小缩略图后,进入高清 ...

  4. SQL Prompt 格式化SQL会自动插入分号的问题

    一.问题 安装新版SQL Prompt,格式化SQL都会自动在SQL末端插入分号 格式化前 格式化后 二.解决方法 选择SQL Prompt下的Options... 选择左侧的Format下Style ...

  5. Javascript面向对象三大特性(封装性、继承性、多态性)详解及创建对象的各种方法

    Javascript基于对象的三大特征和C++,Java面向对象的三大特征一样,都是封装(encapsulation).继承(inheritance )和多态(polymorphism ).只不过实现 ...

  6. JavaScript 对象、DOM对象、jquery对象的区别、转换详解

    一.JavaScript 对象 JavaScript 提供多个内建对象,比如 String.Date.Array 等等. 对象只是带有属性和方法的特殊数据类型. 访问对象的属性: [javascrip ...

  7. Android 平滑图片加载和缓存库 Glide 使用详解

    在图片加载库烂大街的今天,选择一个适合自己使用的图片加载库已经成为了每一个Android开发者的必经之路.现在市面上知名的图片加载库有UIL,Picasso,Volley ImageLoader,Fr ...

  8. php中自动加载类_autoload()和spl_autoload_register()实例详解

    一._autoload 自动加载类:当我们实例化一个未定义的类时,就会触此函数.到了php7.1以后版本不支持此函数好像抛弃了 新建一个类文件名字自己随便去:news类在auto.php文件里面去实例 ...

  9. Spring Cloud Alibaba基础教程:Nacos配置的加载规则详解

    前情回顾: <Spring Cloud Alibaba基础教程:使用Nacos实现服务注册与发现> <Spring Cloud Alibaba基础教程:支持的几种服务消费方式(Res ...

  10. [Aaronyang] 写给自己的WPF4.5 笔记6[三巴掌-大数据加载与WPF4.5 验证体系详解 2/3]

    我要做回自己--Aaronyang的博客(www.ayjs.net) 博客摘要: Virtualizing虚拟化DEMO 和 大数据加载的思路及相关知识 WPF数据提供者的使用ObjectDataPr ...

随机推荐

  1. 小闫s人格大爆发 | 坐椅子上?study:sleep

    hadoop视频 搭建环境 刷单词 看电影

  2. 有什么巨好用Excel数据分析技巧?

    当涉及Excel数据分析时,以下是一些非常实用的技巧和功能,供您参考.这里将为您提供关于数据整理.数据清洗.统计分析.可视化和高级分析等方面的技巧. 一.数据整理与清洗: 导入数据:使用 Excel ...

  3. MCube动态化与原生工程结合最佳实践

    跨端动态化开发方案重要性日益凸显,本文对我们团队MCube动态化实践做了总结,为大家提供经验和借鉴. 接入背景 随着我们工程的需求迭代,暴露出了业务需求量大,分端开发和发版更新成本高等痛点,使用H5页 ...

  4. [UOJ216][UNR#2 2A] Jakarta Skyscrapers

    印尼首都雅加达市有 $10^{18}$ 座摩天楼,它们排列成一条直线,我们从左到右依次将它们编号为 $1$ 到 $10^{18}$ .除了这 $10^{18}$ 座摩天楼外,雅加达市没有其他摩天楼. ...

  5. 基于.NET Core + Quartz.NET+ Vue + IView开箱即用的定时任务UI

    前言 定时任务调度应该是平时业务开发中比较常见的需求,比如说微信文章定时发布.定时更新某一个业务状态.定时删除一些冗余数据等等.今天给大家推荐一个基于.NET Core + Quartz.NET + ...

  6. ubuntu 22.04搭建本地源

    ubuntu 22.04搭建本地源 基于服务器无法联网的情况下,从一台可以上网的服务器下载软件包和依赖,再在无法联网的服务器中搭建本地源,安装环境. 下载(包括依赖): cd /root mkdir ...

  7. 华企盾DSC:wps个人模式无策略组新建的文件仍然加密

    解决方法:右键wps安装目录手动解密即可(原因:wps模板被加密导致)

  8. 在Linux服务器上装jenkins(方式一:war包)

    官网下载jenkins https://www.jenkins.io/zh/download/ 官网下载太慢,可以去清华镜像下载(百度搜索:清华镜像) 下载的文件是jenkins.war 把安装文件放 ...

  9. C# 多线程 progressbar 界面不卡顿简单用法

    多线程进度条的简单使用,界面不卡顿.如下图: 简单源码如下: using System; using System.Collections.Generic; using System.Componen ...

  10. 带你认识一下多模态对比语言图像预训练CLIP

    本文分享自华为云社区<多模态对比语言图像预训练CLIP:打破语言与视觉的界限>,作者:汀丶. 一种基于多模态(图像.文本)对比训练的神经网络.它可以在给定图像的情况下,使用自然语言来预测最 ...