615.md 7.3 KB
Newer Older
Lab机器人's avatar
readme  
Lab机器人 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294
# 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); 
```