随着近两年前端工具领域的一些重大变化,我不仅重新考虑了前端的构建方式,还重新考虑了代码的编写方式。
我已经从Webpack和Parcel换到了Vite,从 JavaScript 换到了 TypeScript,基于类/对象的组件换到了基于 Hook/Composition 的组件。现在随着边缘计算的到来,也许我会花更多的时间使用 Next、Remix 和 Nuxt 等元框架。
最近,我一直在思考的一个多年来没有想过的东西:分号。
其实,您对 JavaScript 的任何看法,都可能是对的。此时,有一个问题又被提出:我们真的需要 JavaScript 中的分号吗?
从技术的角度来说
从技术的角度来说,在现代的前端领域,这个问题的答案是否定的。
现在,几乎所有新的前端项目都以由 CLI 或者 npm 初始化程序开始的,它们都可以选择(或者默认包含)linting、格式化、转译和编译的工具。
我们设置这些基础标准,为了让开发的体验更好,并在团队之间保持代码一致。有了这些工具的帮助,我认为可以不要 JavaScript 中的分号。当然,这个问题没有正确答案,完全是个人喜好问题。
为什么说 JavaScript 中的分号很尴尬
需要明确说明的是,分号本身并不尴尬,尴尬的插入分号这件事儿。在技术上,分号有无是“可选的”,但是它确实会导致一些异常情况。
关于分号,ESLint 文档解释得很好,说明如下:
JavaScript 不需要在每条语句的末尾使用分号。在许多情况下,JavaScript 引擎可以确定分号应该在某个位置并自动添加它。该功能称为 自动分号插入 (ASI) ,这被认为是 JavaScript 中更具争议的功能之一。
例如,下面的代码是正确的:
var name = "ESLint"
var website = "eslint.org";
在第一行,JavaScript 引擎会自动插入一个分号,所以这不被认为是语法错误。JavaScript 的引擎知道如何解释该行代码,并且知道行尾表示语句结束了。
分号可能会导致两种异常问题的发生:
- 无法访问的代码
- 意外的多行代码
首先,看第一点
示例代码如下:
return
{
name: "ESLint"
};
JavaScript 引擎会将这段代码解释为:
return;
{
name: "ESLint";
}
这样就会造成 return
后直接返回,导致它下面的代码无法访问。
然后,看第二点
示例代码如下:
var globalCounter = { }
(function () {
var n = 0
globalCounter.increment = function () {
return ++n
}
})()
JavaScript 引擎会将这段代码解释为:
var globalCounter = { }
(function () {
var n = 0
globalCounter.increment = function () {
return ++n
}
})();
JavaScript 引擎不会在第一行之后插入分号,从而导致运行时错误(误将空对象作为函数调用)。
使用工具
现在,我们已经了解了分号在 JavaScript 中是如何工作的。接下来介绍一下使用哪些工具可以避免上面遇到的异常情况。
常见的有三个工具:
- ESLint
- Prettier
- TypeScript Compiler (TSC) 这三个工具可以很好地协同工作,每个都可以针对前面描述的异常情况提供对应的保护机制。
ESLint
ESLint是最流行的 JavaScript linter。它的配置非常灵活,并带有开箱即用的推荐规则。
要配置 ESLint 在不使用分号的情况下也可以正常工作,只需要指定三个规则:semi、no-unreachable和no-unexpected-multiline。
可以将下面的代码片段添加到块.eslintrc.{js,yml,json}
下的配置文件rule
中:
rules: {
semi: ['error', 'never'],
'no-unreachable': ['error'],
'no-unexpected-multiline': ['error']
}
Prettier
Prettier是一个专一的代码格式化工具,唯一的目的就是格式化你的代码。
一般情况下,Prettier 会与 ESLint 一起配合使用,效果更佳。
我们可以将 Prettier 配置为自动从代码中删除分号,需要在.prettierrc.json
配置文件中增加如下设置:
{
"semi": false
}
TSC
TypeScript 编译器是这三个工具中最简单的,因为它不需要配置就可以使用没有分号的语言。只要您使用 TypeScript 语言开发。
虽然它没有涵盖所有边缘情况,但当其中一些 ASI 故障导致对 TypeScript 类型系统的无效使用时,编译器会发出错误。
何时使用分号
尽管,上述工具可以帮助我们处理没有分号的异常情况,但是仍然有一些情况可以使用分号:
- 直接在浏览器/网页中编写代码
- 在没有良好工具支持的项目或环境中编写代码
- 你是 JavaScript 新手
- 只是因为你想