ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
# JavaScript style guide > 原文:[https://docs.gitlab.com/ee/development/fe_guide/style/javascript.html](https://docs.gitlab.com/ee/development/fe_guide/style/javascript.html) * [Avoid forEach](#avoid-foreach) * [Limit number of parameters](#limit-number-of-parameters) * [Avoid classes to handle DOM events](#avoid-classes-to-handle-dom-events) * [Pass element container to constructor](#pass-element-container-to-constructor) * [Use ParseInt](#use-parseint) * [CSS Selectors - Use `js-` prefix](#css-selectors---use-js--prefix) * [ES Module Syntax](#es-module-syntax) * [Absolute vs relative paths for modules](#absolute-vs-relative-paths-for-modules) * [Do not use `DOMContentLoaded` in non-page modules](#do-not-use-domcontentloaded-in-non-page-modules) * [Avoid XSS](#avoid-xss) * [Avoid single-line conditional statements](#avoid-single-line-conditional-statements) * [ESLint](#eslint) * [IIFEs](#iifes) * [Global namespace](#global-namespace) * [Side effects](#side-effects) * [Top-level side effects](#top-level-side-effects) * [Avoid side effects in constructors](#avoid-side-effects-in-constructors) * [Pure Functions and Data Mutation](#pure-functions-and-data-mutation) # JavaScript style guide[](#javascript-style-guide "Permalink") 我们使用[Airbnb 的 JavaScript 样式指南](https://github.com/airbnb/javascript)及其附带的 linter 来管理我们的大多数 JavaScript 样式指南. 除了由 Airbnb 设置的样式准则之外,我们还列出了以下一些特定规则. > **提示:**您可以通过运行`yarn eslint`在本地运行`yarn eslint` ## Avoid forEach[](#avoid-foreach "Permalink") 变异数据时避免 forEach. 更改数据时,请使用`map` , `reduce`或`filter`而不是`forEach` . 这样可以最大程度地减少功能上的变化,从而与[Airbnb 的风格指南](https://github.com/airbnb/javascript#testing--for-real)保持一致. ``` // bad users.forEach((user, index) => { user.id = index; }); // good const usersWithId = users.map((user, index) => { return Object.assign({}, user, { id: index }); }); ``` ## Limit number of parameters[](#limit-number-of-parameters "Permalink") 如果您的函数或方法具有三个以上的参数,请改为使用对象作为参数. ``` // bad function a(p1, p2, p3) { // ... }; // good function a(p) { // ... }; ``` ## Avoid classes to handle DOM events[](#avoid-classes-to-handle-dom-events "Permalink") 如果该类的唯一目的是绑定 DOM 事件并处理回调,则最好使用函数. ``` // bad class myClass { constructor(config) { this.config = config; } init() { document.addEventListener('click', () => {}); } } // good const myFunction = () => { document.addEventListener('click', () => { // handle callback here }); } ``` ## Pass element container to constructor[](#pass-element-container-to-constructor "Permalink") 当您的类操作 DOM 时,将元素容器作为参数接收. 这样更易于维护和执行. ``` // bad class a { constructor() { document.querySelector('.b'); } } // good class a { constructor(options) { options.container.querySelector('.b'); } } ``` ## Use ParseInt[](#use-parseint "Permalink") 将数字字符串转换为数字时,请使用`ParseInt` . ``` // bad Number('10') // good parseInt('10', 10); ``` ## CSS Selectors - Use `js-` prefix[](#css-selectors---use-js--prefix "Permalink") 如果仅在 JavaScript 中使用 CSS 类作为对元素的引用,则使用`js-`作为类名的前缀. ``` // bad <button class="add-user"></button> // good <button class="js-add-user"></button> ``` ## ES Module Syntax[](#es-module-syntax "Permalink") 使用 ES 模块语法导入模块: ``` // bad const SomeClass = require('some_class'); // good import SomeClass from 'some_class'; // bad module.exports = SomeClass; // good export default SomeClass; ``` *注意:*我们仍然在`scripts/`和`config/`文件中使用`require` . ## Absolute vs relative paths for modules[](#absolute-vs-relative-paths-for-modules "Permalink") 如果要导入的模块少于两个级别,请使用相对路径. ``` // bad import GitLabStyleGuide from '~/guides/GitLabStyleGuide'; // good import GitLabStyleGuide from '../GitLabStyleGuide'; ``` 如果要导入的模块为两个或两个以上级别,请改用绝对路径: ``` // bad import GitLabStyleGuide from '../../../guides/GitLabStyleGuide'; // good import GitLabStyleGuide from '~/GitLabStyleGuide'; ``` Additionally, **不添加到全局名称空间**. ## Do not use `DOMContentLoaded` in non-page modules[](#do-not-use-domcontentloaded-in-non-page-modules "Permalink") 导入的模块每次加载时都应发挥相同的作用. `DOMContentLoaded`事件仅允许在`/pages/*`目录中加载的模块上使用,因为这些事件是通过 webpack 动态加载的. ## Avoid XSS[](#avoid-xss "Permalink") 不要使用`innerHTML` , `append()`或`html()`设置内容. 它打开了太多的漏洞. ## Avoid single-line conditional statements[](#avoid-single-line-conditional-statements "Permalink") 缩进在扫描代码时很重要,因为它可以快速指示分支,循环和返回点的存在. 这可以帮助快速了解控制流程. ``` // bad if (isThingNull) return ''; if (isThingNull) return ''; // good if (isThingNull) { return ''; } ``` ## ESLint[](#eslint "Permalink") ESLint 行为可以在我们的[工具指南中](../tooling.html)找到. ## IIFEs[](#iifes "Permalink") 避免使用 IIFE(立即调用函数表达式). 尽管我们有很多将其内容包装在 IIFE 中的文件示例,但是从 Sprockets 过渡到 Webpack 之后,这不再是必需的. 重构遗留代码时,请不要再使用它们,并随时将其删除. ## Global namespace[](#global-namespace "Permalink") 避免添加到全局名称空间. ``` // bad window.MyClass = class { /* ... */ }; // good export default class MyClass { /* ... */ } ``` ## Side effects[](#side-effects "Permalink") ### Top-level side effects[](#top-level-side-effects "Permalink") 在任何包含`export`脚本中都禁止顶级副作用: ``` // bad export default class MyClass { /* ... */ } document.addEventListener("DOMContentLoaded", function(event) { new MyClass(); } ``` ### Avoid side effects in constructors[](#avoid-side-effects-in-constructors "Permalink") 避免在`constructor`进行异步调用,API 请求或 DOM 操作. 而是将它们移动到单独的函数中. 这将使测试更易于编写,并且避免违反[单一职责原则](https://en.wikipedia.org/wiki/Single_responsibility_principle) . ``` // bad class myClass { constructor(config) { this.config = config; axios.get(this.config.endpoint) } } // good class myClass { constructor(config) { this.config = config; } makeRequest() { axios.get(this.config.endpoint) } } const instance = new myClass(); instance.makeRequest(); ``` ## Pure Functions and Data Mutation[](#pure-functions-and-data-mutation "Permalink") 努力编写许多小的纯函数,并尽量减少发生突变的地方 ``` // bad const values = {foo: 1}; function impureFunction(items) { const bar = 1; items.foo = items.a * bar + 2; return items.a; } const c = impureFunction(values); // good var values = {foo: 1}; function pureFunction (foo) { var bar = 1; foo = foo * bar + 2; return foo; } var c = pureFunction(values.foo); ```