JavaScript中自动插入分号的规则详解

 更新时间:2024年01月19日 08:38:41   作者:全栈李林  
JavaScript 提供了 automatic semicolon insertion (ASI)自动插入分号规则,在不加分号的情况下,会自动补充分号来分隔不同语句,下面我们就来具体了解一下这一规则吧

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后面不能插入换行;
  • 后自增、后自减运算符前不能插入换行;
  • throwException之间不能插入换行;
  • 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 、forwhile 等语句 } 后写分号,但是如果使用赋值的形式传递,则一定要注意在 } 把分号添加上,以避免后面语句出现自执行和数组开头的语句。

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

总结

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

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

以上就是JavaScript中自动插入分号的规则详解 的详细内容,更多关于JavaScript自动插入分号的资料请关注脚本之家其它相关文章!

相关文章

  • 详解JavaScript是如何验证URL的

    详解JavaScript是如何验证URL的

    当开发者需要为不同目的以不同形式处理URL时,我们经常会借助于JavaScript。本文就为大家整理了JavaScript验证URL的方法,希望对大家有所帮助
    2023-02-02
  • js实现做通讯录的索引滑动显示效果和滑动显示锚点效果

    js实现做通讯录的索引滑动显示效果和滑动显示锚点效果

    下面小编就为大家带来一篇js实现做通讯录的索引滑动显示效果和滑动显示锚点效果。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • js面向对象之公有、私有、静态属性和方法详解

    js面向对象之公有、私有、静态属性和方法详解

    这篇文章主要详细介绍了js面向对象之公有、私有、静态属性和方法,并附上详细的示例,非常的细致全面,这里推荐给大家,有需要的小伙伴可以参考下
    2015-04-04
  • javascript中CheckBox全选终极方案

    javascript中CheckBox全选终极方案

    在javascript页面中实现CheckBox或者Radio的选中状态是一件很容易的事情,下面我们来给大家展示下在asp.net中使用javascript中CheckBox全选终极方案,有需要的小伙伴可以参考下。
    2015-05-05
  • 利用JS判断用户是否上网(连接网络)

    利用JS判断用户是否上网(连接网络)

    本篇文章主要介绍了利用JS判断用户是否上网(连接网络)。需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • 解决layui页面按钮点击无反应,也不报错的问题

    解决layui页面按钮点击无反应,也不报错的问题

    今天小编就为大家分享一篇解决layui页面按钮点击无反应,也不报错的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • 一个很Cool的JS菜单效果

    一个很Cool的JS菜单效果

    [蓝色]一个很Cool的JS菜单效果...
    2006-09-09
  • JavaScript操作DOM样式的各种方法小结

    JavaScript操作DOM样式的各种方法小结

    在现代Web开发中,动态操作DOM元素的样式是创建交互式用户体验的核心技能之一,无论是响应用户操作、实现动画效果,还是根据应用状态改变界面外观,都离不开对DOM样式的精确控制,本文将全面介绍JavaScript中操作DOM样式的各种方法,从基础概念到高级技巧
    2025-06-06
  • 利用JS实现文字的聚合动画效果

    利用JS实现文字的聚合动画效果

    这篇文章主要给大家介绍了利用JS如何实现文字的聚合动画效果,实现的效果非常不错,类似粒子动画的效果,有需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-01-01
  • JavaScript中Map与reduce的应用小结

    JavaScript中Map与reduce的应用小结

    Map构造函数创建一个新Map对象,它允许以键值对的形式存储数据,提供了一种更加灵活的数据结构,本文给大家介绍JavaScript中Map与reduce的应用小结,感兴趣的朋友一起看看吧
    2024-06-06

最新评论