原文:Let’s talk about semicolons in JavaScript,作者:Flavio Copes
使用还是不使用分号,这是一个问题
关于 JavaScript 中的分号(即 ;)的使用,社区中存在分歧。有些人在任何情况下都喜欢使用分号,而有些人则倾向于避免使用分号。
我在 Twitter 上做了一个投票来测试,我发现有很多分号的支持者。
在使用分号多年后,2017 年秋天,我决定尝试在可能的情况下避免使用分号。我设置了 Prettier,以自动从我的代码中删除分号,除非有特定的代码结构需要它们。
现在我发现避免分号是很自然的,而且我认为代码看起来更好,读起来也更干净。
这一切之所以可能,是因为 JavaScript 并不严格要求分号。当有地方需要分号时,它会在背后悄悄地添加分号。
这被称为自动分号插入(Automatic Semicolon Insertion)。
了解分号的语法规则是很重要的。这将使你在写代码时避免产生 bug 导致代码不按你的预期运行。
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()
基于规则 4 的另一个例子:
(() => {
return
{
color: 'white'
}
})()
你会期望这个立即调用的函数的返回值是一个包含 color
属性的对象,但它不是。相反,它是 undefined
,因为 JavaScript 在 return
后面插入了一个分号。
相反,你应该在 return
后面加上括号:
(() => {
return {
color: 'white'
}
})()
你会认为这段代码在警报中显示 0
:
1 + 1
-1 + 1 === 0 ? alert(0) : alert(2)
但它显示的是 2,因为 JavaScript(根据规则 1)将其解释为:
1 + 1 -1 + 1 === 0 ? alert(0) : alert(2)
总结
小心——有些人对分号很有分歧。说实话,我并不关心。这个工具给了我们不使用它的选项,所以如果我们愿意,我们可以避免使用分号。
我没有建议任何一方或另一方的做法。只要根据对你有用的东西做出你自己的决定。
不管怎么说,我们只需要注意一下,即使大多数时候这些基本情况从未在你的代码中出现过。
选择一些规则:
- 对
return
语句要小心。如果你要返回什么,请在返回的同一行添加(对break
、throw
、continue
也是如此)。 - 不要用圆括号(即
(
)开始一行,因为这些圆括号可能会与前一行串联起来,形成一个函数调用,或一个数组元素引用。
最后,一定要测试你的代码,确保它能达到你的要求。
我每天在 flaviocopes.com上发布一个免费的编程教程,你可以学习!
原文发表于 flaviocopes.com.