- 前言
- 关于 ECMASCRIPT 发展史和现状
- ES6 带来的重大特性
- ES2016(ES7)的改进
- ES2017(ES8)带来的重大新特性
- ES2018(ES9)带来的重大新特性
- JavaScript 编码风格指南
- JavaScript 词法结构(构建块)
- JavaScript 变量
- JavaScript 数据类型
- JavaScript 表达式
- 原型继承
- 如何使用 JavaScript 中的 Classes(类)
- JavaScript 异常处理
- JavaScript 中的分号(;)
- JavaScript 中的引号
- JavaScript 字面量模板(Template Literals)指南
- JavaScript 中的 function(函数)
- JavaScript 箭头函数(Arrow Function)
- JavaScript 中的闭包(Closures)
- JavaScript 数组(Arrays)
- JavaScript 中的循环(Loops)
- JavaScript 中的事件(Events)
- JavaScript 中的事件循环(Event Loop)
- JavaScript 异步编程和回调
- 理解 JavaScript 中的 Promises
- 用 async 和 await 编写现代 JavaScript 异步代码
- JavaScript 中的 循环(Loops) 和 作用域(Scope)
- JavaScript 定时器 setTimeout() 和 setInterval()
- JavaScript 中的 this
- JavaScript 严格模式(Strict Mode)
- JavaScript 中的 立即执行函数表达式(IIFE)
- JavaScript 中的数学运算符
- JavaScript 中的 Math 对象
- 介绍 ES Modules(模块)
- 介绍 CommonJS
- JavaScript 术语表
JavaScript 中的分号(;)
JavaScript 中的分号是可选的。 我个人偏好是我的代码中避免使用分号,但也有很多人使用分号。
有一件大家看起来不可思议的事情就是,JavaScript 因为该不该使用分号而划分成了 2 个社区。 有些人无论如何都喜欢随时使用分号。 其他人则更喜欢避免使用它们。
我也是使用分号多年,在 2017 年秋天,我决定尝试尽量地避免使用它们,我确实设置了 Prettier 来自动删除代码中的分号,除非有特定的代码构造需要它们。
现在我发现避免使用分号是很自然的,我认为代码看起来更好,阅读更清晰。
JavaScript 并不严格要求使用分号。 当有一个需要分号的地方时,JavaScript 会在解析时自动添加。
执行此操作的过程称为自动插入分号。
了解必须使用分号的规则非常重要,以避免编写产生错误的代码,因为它们的行为可能会与您预期的不同。
JavaScript 自动插入分号 的规则
JavaScript 并不是在所有换行处都填补分号:只有在缺少了分号就无法正确解析代码的时候,JavaScript 才会填补分号。在解析源代码期间,要是发现以下特定的情况时,JavaScript 解析器 将会自动添加分号 :
- 当下一行代码开始会破坏当前一行的代码时( JavaScript 代码可以写在多行中 )。如果一条语句以
(
、[
、/
、+
或-
开始,那么它极有可能和前面一条语句合在一起解析。 - 当下一行以
}
开头时,或者以}
结束闭合当前代码块时 - 当解析到达源代码文件的末尾时
- 当前行
return
语句后面紧跟着换行时 - 当前行
break
语句后面紧跟着换行时 - 当前行
throw
语句后面紧跟着换行时 - 当前行
continue
语句后面紧跟着换行时
不符合你预期的代码示例
基于上面这些规则,这里有一些例子。
先来看看这个:
const hey = 'hey' const you = 'hey' const heyYou = hey + ' ' + you ['h', 'e', 'y'].forEach((letter) => console.log(letter))
您将收到错误 Uncaught TypeError: Cannot read property 'forEach' of undefined
,因为基于规则 1 JavaScript 尝试将代码解析为:
const hey = 'hey'; const you = 'hey'; const heyYou = hey + ' ' + you['h', 'e', 'y'].forEach((letter) => console.log(letter))
还有类似下面的代码:
(1 + 2).toString()
这里会打印 3
。
const a = 1 const b = 2 const c = a + b (a + b).toString()
而这里的代码会引发 TypeError: b is not a function
异常,因为 JavaScript 试图将其解释为:
const a = 1 const b = 2 const c = a + b(a + b).toString()
您认为此代码在 alert 中显示为“0”:
1 + 1 -1 + 1 === 0 ? alert(0) : alert(2)
但其实显示 2 ,因为规则 1 的 JavaScript 将其解释为:
1 + 1 -1 + 1 === 0 ? alert(0) : alert(2)
再来看看下面的注释
var // 这一行不会插入分号 ,因为 下一行的代码不会破坏当前行的代码 a = 1 // 这一行会插入分号 let b = 2 // 再比如这种情况,你的原意可能是定义 `a` 变量,再执行 `(a + 3).toString()`, // 但是其实 JavaScript 解析器解析成了,`var a = 2(a + 3).toString()`, // 这时会抛出错误 Uncaught TypeError: 2 is not a function var a = 2 (a + 3).toString() // 同理,下面的代码会被解释为 `a = b(function(){...})()` a = b (function(){ ... })()
另一个基于规则 4 的例子:
(() => { return { color: 'white' } })()
您希望这个立即调用函数的返回值是一个包含 color
属性的对象,但事实并非如此。 相反,它是 undefined
,因为 JavaScript 在 return
后插入分号。
相反,您应该在 return
后立即放置花括号 {
,因为当前行 return
语句后面紧跟着换行时 ,JavaScript 解析器将会自动添加分号:
(() => { return { color: 'white' } })()
结论
有些人非常坚持使用分号。 老实说我并不喜欢使用分号,很多工具为我们提供了不使用分号的选项,我们完全可以避免使用分号。但是我们仍然需要注意一些细节,即使大多数情况下这些基本场景不会在我们的代码中出现。
当然这是个人的喜好问题,我也不会试图说服你避免使用分号。
使用分号的一些规则:
- 请注意
return
语句。 如果你想返回一些东西,把它添加到与return
同一行上(同样用于break
,throw
,continue
)。 - 永远不要用
(
、[
、/
、+
或-
开始一行,这些可能与前一行连接以形成函数调用或数组元素引用。
最后,始终测试您的代码,以确保结果是你想要的。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论