这篇文章分享了我编写 JavaScript 代码时遵循的一套规则。但在我们深入探讨之前,我必须告诉您,我使用 JavaScript 的方式有点不同寻常。我的主要目的是仅使用一种编程语言进行高级开发,而不是 C#、F#、Java、Scala、Python 等。因此,我尽量避免非通用的 JavaScript 框架和特定于平台的工具。对于低级别和系统编程,我使用 Rust,并考虑使用 Zig 编程语言。
TypeScript 作为代码检查工具
虽然我非常喜欢静态类型,并对 TypeScript 项目印象深刻,但我不再在我的项目中使用 TypeScript 的 .ts 文件。主要原因是为了避免构建步骤。一个项目应该在没有任何构建步骤的情况下即可使用。但是,我使用 TypeScript 编译器作为代码检查工具,并使用 JSDoc 作为类型定义。要将 TypeScript 编译器用作代码检查工具,您需要在 tsconfig.json 文件中设置以下属性:
代码语言:json复制{
"compilerOptions": {
...
"allowJs": true,
"checkJs": true,
...
"noEmit": true,
...
}
}
希望有朝一日,我们将看到 ECMAScript 的类型注解提案,并得到流行 JavaScript 引擎的支持。
不使用类或符号
我认为用户定义的名义类型在确定性分布式系统中没有未来。JavaScript 类存在两个主要问题:
类是 JavaScript 名义类型系统的一部分,与 TypeScript 的结构类型系统相反。名义类型是基于位置而不是内容的。这意味着类的识别是根据它的定义位置而不是其内容。基于位置的标识非常难以扩展并且会创建依赖地狱。
类的序列化和反序列化需要额外的代码。这段代码通常没有任何语义意义,是一种反模式。请改用标准的 JavaScript 对象和数组;它们可以仅通过一个函数调用进行序列化和反序列化。
JavaScript 符号具有与类相同的可扩展性问题。
函数式编程
尽可能多地使用函数式编程和纯函数。例如:
不要直接使用 I/O。直接 I/O 是副作用的主要来源。您可以使用依赖注入。不要直接写入文件,而是使用传递的函数来写入文件。这将使您更轻松地测试代码。
避免可变性,或尝试将数据变异限制在局部范围内。
使用箭头函数和柯里化而不是多个参数。
您可以在这篇文章中了解更多关于 JavaScript 中的函数式编程。
使用 ECMAScript 模块
ECMAScript 模块受到大多数现代 JavaScript 引擎和浏览器的支持。为避免与其他模块系统混淆,使用 .mjs 文件扩展名而不是 .js。目前,我仅使用 export default,因为它与加载 JSON 文件和 CommonJS 系统一致。我只想使用一种导出方法,并更喜欢简单性而不是语法糖。
代码语言:javascript复制import my from './export-default.mjs'
const { a, b } = my
而不是
代码语言:javascript复制import { a, b } from './export.mjs'
没有充分理由时避免第三方依赖
开发依赖项,如 TypeScript 或 ESLint,如果不需要额外的构建步骤,是可以的。尽量避免使用直接 I/O 或特定于平台的库和框架。它们将使您的代码非常难以测试。
这套规则并非适用于所有人。如果您在一个具有庞大现有代码库的大公司工作,这可能不适合您。但是,如果您正在进行新项目,或者您是创业公司,或者您正在进行开源项目,您可以考虑这些观点。不要急于用难以维护的复杂事物感染您的代码库。请尽可能保持简单,只在必要时添加复杂性。
我正在参与2023腾讯技术创作特训营第三期有奖征文,组队打卡瓜分大奖!