翼度科技»论坛 编程开发 JavaScript 查看内容

JavaScript到底应不应该加分号?JavaScript自动插入分号规则详解

8

主题

8

帖子

24

积分

新手上路

Rank: 1

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

ASI 自动插入分号规则

在决定是否添加分号之前,我们先来了解一下编译器到底在哪些情况下会自动插入分号,哪些情况必须手动添加分号。
会自动添加分号的情况

1.遇到换行符,但是两句代码连接是无效代码
  1. // 代码
  2. 42
  3. 'hello'
  4. // `42 'hello'`连接在一起是无效语句,所以会自动在之间插入分号
  5. 42;'hello'
  6. // 直接明确的写法
  7. 42;"hello"
复制代码
  1. // 代码
  2. let a = 10, b = 5
  3. a
  4. -
  5. b
  6. // a - b 为有效代码,所以三者之间不会自动加分号
  7. a = 1; b = 2;
  8. // 直接明确的写法
  9. a - b
复制代码
2.遇到换行符,但是两句代码之间不允许有换行符
  1. // 代码
  2. foo
  3. ++
  4. bar
  5. ++
  6. baz
  7. // foo 和 ++ 符合规则1,但是不符合 no LineTerminator here规则,所以会添加分号
  8. foo;
  9. ++bar;
  10. ++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 等
  • 反引号`
  1. // return 后空一行再书写语句,则会自动在 return 后加分号
  2. return
  3. {
  4.   a: 1
  5. }
  6. // 这是正确写法
  7. return {
  8.   a: 1
  9. }
复制代码
其它标签类似。
如果手动在这些标签后加上分号,同样也是错误的,比如:
  1. // 空一行再写 a,会自动在 ++ 后添加分号
  2. ++
  3. a
  4. // 就算手动添加,和上面结果一样是错误的
  5. ++;
  6. a;
复制代码
所以针对 Restricted productions ,无论让编译器自动添加分号,还是自己手动加上分号,都是错误的,都应该去避免去换行,避免写这种写法。
必须手动加分号的情况

以下面这些标签开头的命令,必须在前面加分号,和前面一个语句分隔:

  • + 和 -:语句以 + 或者 - 开头
  • /:  语句以正则表达式开头
  • ( :  语句以自执行函数开头
  • [: 语句以数组开头
举例说明:
  1. // 错误
  2. a = b
  3. +a
  4. // 正确
  5. a = b
  6. ;+a
  7. // 错误
  8. a = b
  9. /something/.test(a)
  10. // 正确
  11. a = b
  12. ;/something/.test(a)
  13. // 错误
  14. a = b
  15. (function () {})()
  16. // 正确
  17. a = b
  18. ;(function() {})()
  19. // 错误
  20. a = b
  21. [1, 2, 3].forEach()
  22. // 正确
  23. a = b
  24. ;[1, 2, 3].forEach()
复制代码
上面的情况,如果第二行代码不手动添加分号的话,两行代码会合并在一起导致结果错误或者报错。
上面几种情况中,只有自执行函数和数组开头会在极少情况下遇到,记住这两个前面要手动加上分号即可。
就算是习惯加分号的朋友,但仍然要注意下面的情况:
  1. // 不需要结尾添加分号
  2. if () {
  3. }
  4. // 不需要结尾添加分号
  5. for () {
  6. }
  7. // 不需要结尾添加分号
  8. while () {
  9. }
  10. // 需要在结尾添加分号
  11. var a = function () {
  12. };
  13. // 需要在结尾添加分号
  14. var a = {
  15.   prop: value
  16. };
  17. // 报错
  18. [1, 2, 3].forEach();
复制代码
即便习惯写分号的朋友,也很少有人在 if 、for、while 等语句 } 后写分号,但是如果使用赋值的形式传递,则一定要注意在 } 把分号添加上,以避免后面语句出现自执行和数组开头的语句。
推荐遇到自执行和数组开头的,直接前面加上分号就完事了。
总结

是否添加和是否手动加是两回事,我们可以用 eslint、Prettier 等工具自动生成或者删除分号,是否手动加可以看个人喜好,最终代码内可以根据项目要求用工具生成。
但都要注意必须添加分号的几种情况。
参考文章


来源:https://www.cnblogs.com/easy1996/p/17972476
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
来自手机

举报 回复 使用道具