Airbnb JavaScript 风格指南() {

使用 JavaScript 最合理的方式

注意: 这个指南假定你正在使用 Babel,并且需要你使用 babel-preset-airbnb 或与其等效的预设。同时假定你在你的应用里安装了 带有 airbnb-browser-shims 或与其等效的插件的 shims/polyfills

Downloads Downloads Gitter

这个指南支持的其他语言翻译版请看 Translation

其他风格指南:

目录

  1. 类型
  2. 引用
  3. 对象
  4. 数组
  5. 解构
  6. 字符串
  7. 函数
  8. 箭头函数
  9. 类与构造函数
  10. 模块
  11. 迭代器与生成器
  12. 属性
  13. 变量
  14. 提升
  15. 比较运算符与相等
  16. 控制语句
  17. 注释
  18. 空格
  19. 逗号
  20. 分号
  21. 类型转换与强制转换
  22. 命名规范
  23. Get-Set 访问器
  24. 事件
  25. jQuery
  26. ECMAScript 5 兼容性
  27. ECMAScript 6+ (ES 2015+) 风格
  28. 标准库
  29. 测试
  30. 性能
  31. 资源
  32. In the Wild
  33. Translation
  34. The JavaScript Style Guide Guide
  35. Chat With Us About JavaScript
  36. Contributors
  37. License
  38. Amendments

类型

⬆ 回到顶部

引用

⬆ 返回顶部

对象

  // very bad
  const original = { a: 1, b: 2 };
  const copy = Object.assign(original, { c: 3 }); // this mutates `original` ಠ_ಠ
  delete copy.a; // so does this

  // bad
  const original = { a: 1, b: 2 };
  const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }

  // good es6 扩展运算符 ...
  const original = { a: 1, b: 2 };
  // 浅拷贝
  const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }

  // rest 解构运算符
  const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

⬆ 返回顶部

数组

⬆ 返回顶部

解构

⬆ back to top

字符串

为什么?字符串折行增加编写难度且不易被搜索。

```javascript
// bad
const errorMessage = 'This is a super long error that was thrown because \
of Batman. When you stop to think about how Batman had anything to do \
with this, you would get nowhere \ fast.';

// bad
const errorMessage = 'This is a super long error that was thrown because ' +
  'of Batman. When you stop to think about how Batman had anything to do ' +   'with this, you would get nowhere fast.';

// good
const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
```

⬆ 返回顶部

函数

    // bad
    function foo() {
      // ...
    }

// bad
    const foo = function () {
      // ...
    };

// good
    // lexical name distinguished from the variable-referenced invocation(s)
    // 函数表达式名和声明的函数名是不一样的
    const short = function longUniqueMoreDescriptiveLexicalFoo() {
      // ...
    };

⬆ 返回顶部

箭头函数

// good foo(() => { bool = true; }); ```

// bad [1, 2, 3].map(x => { const y = x + 1; return x * y; });

// good
[1, 2, 3].map((x) => {
  const y = x + 1;
  return x * y;
});
```

⬆ 返回顶部

类与构造函数

⬆ 返回顶部

模块

为什么?鼓励使用更多文件,每个文件只导出一次,这样可读性和可维护性更好。

    // bad
    export function foo() {}

// good
    export default function foo() {}

⬆ 返回顶部

迭代器与生成器

⬆ 返回顶部

属性

⬆ 返回顶部

变量

⬆ 返回顶部

提升

⬆ 返回顶部

比较运算符与相等

⬆ back to top

⬆ 返回顶部

控制语句

⬆ 返回顶部

注释

⬆ 返回顶部

空格

// bad
class Person {
  constructor(fullName, email, birthday) {
    this.fullName = fullName;


    this.email = email;


    this.setAge(birthday);
  }


  setAge(birthday) {
    const today = new Date();


    const age = this.getAge(today, birthday);


    this.age = age;
  }


  getAge(today, birthday) {
  // ..
  }
}

// good
class Person {
  constructor(fullName, email, birthday) {
    this.fullName = fullName;
    this.email = email;
    this.setAge(birthday);
	}

  setAge(birthday) {
    const today = new Date();
    const age = getAge(today, birthday);
    this.age = age;
  }

  getAge(today, birthday) {
  	// ..
  }
}

var y = 2;

// bad - 2+ newlines at end of file var x = 1; var y = 2;

// bad - 1+ newline(s) at beginning of file

var x = 1; var y = 2;

// good var x = 1; var y = 2;


**[⬆ 返回顶部](#目录)**

## 逗号

  <a name="20.1"></a>
  <a name="commas--leading-trailing"></a>
  - [20.1](#commas--leading-trailing) 不要前置逗号。eslint: [`comma-style`](http://eslint.org/docs/rules/comma-style.html)

    ```javascript
    // bad
    const story = [
        once
      , upon
      , aTime
    ];

    // good
    const story = [
      once,
      upon,
      aTime,
    ];

    // bad
    const hero = {
        firstName: 'Ada'
      , lastName: 'Lovelace'
      , birthYear: 1815
      , superPower: 'computers'
    };

    // good
    const hero = {
      firstName: 'Ada',
      lastName: 'Lovelace',
      birthYear: 1815,
      superPower: 'computers',
    };
    ```

  <a name="20.2"></a>
  <a name="commas--dangling"></a>

  - [20.2](#commas--dangling) 额外结尾逗号: **要** eslint: [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle.html)

    > 为什么?这使 git diffs 更简洁。此外,像Babel这样的转换器会删除转换代码中的额外的逗号,这意味着你不必担心旧版浏览器中的 [结尾逗号问题](https://github.com/airbnb/javascript/blob/es5-deprecated/es5/README.md#commas)。

    ```diff
    // bad - 没有结尾逗号的 git diff
    const hero = {
         firstName: 'Florence',
    -    lastName: 'Nightingale'
    +    lastName: 'Nightingale',
    +    inventorOf: ['coxcomb chart', 'modern nursing']
    };

    // good - 有结尾逗号的 git diff
    const hero = {
         firstName: 'Florence',
         lastName: 'Nightingale',
    +    inventorOf: ['coxcomb chart', 'modern nursing'],
    };
    ```

    ```javascript
    // bad
    const hero = {
      firstName: 'Dana',
      lastName: 'Scully'
    };

    const heroes = [
      'Batman',
      'Superman'
    ];

    // good
    const hero = {
      firstName: 'Dana',
      lastName: 'Scully',
    };

    const heroes = [
      'Batman',
      'Superman',
    ];

    // bad
    function createHero(
      firstName,
      lastName,
      inventorOf
    ) {
      // does nothing
    }

    // good
    function createHero(
      firstName,
      lastName,
      inventorOf,
    ) {
      // does nothing
    }

    // good (注意,逗号不应出现在使用了 ... 操作符后的参数后面)
    function createHero(
      firstName,
      lastName,
      inventorOf,
      ...heroArgs
    ) {
      // does nothing
    }

    // bad
    createHero(
      firstName,
      lastName,
      inventorOf
    );

    // good
    createHero(
      firstName,
      lastName,
      inventorOf,
    );

    // good  (注意,逗号不应出现在使用了 ... 操作符后的参数后面)
    createHero(
      firstName,
      lastName,
      inventorOf,
      ...heroArgs
    )
    ```

**[⬆ 返回顶部](#目录)**


## 分号

  <a name="21.1"></a>
  - [21.1](#21.1) **要分号!** eslint: [`semi`](http://eslint.org/docs/rules/semi.html)

    > 为什么?当 JavaScript 遇到没有分号结尾的一行,它会执行 [自动插入分号](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) 这一规则来决定行末是否加分号。如果 JavaScript 在你的断行里错误的插入了分号,就会出现一些古怪的行为。当新的功能加到JavaScript 里后, 这些规则会变得更复杂难懂。清晰的结束语句,并通过配置代码检查去检查没有带分号的地方可以帮助你防止这种错误。

```javascript
// bad - 抛出异常
const luke = {}
const leia = {}
[luke, leia].forEach((jedi) => jedi.father = 'vader')

// bad - 抛出异常
const reaction = "No! That’s impossible!"
(async function meanwhileOnTheFalcon() {
  // 处理 `leia`, `lando`, `chewie`, `r2`, `c3p0`
  // ...
}())

// bad - 将返回 `undefined` 而不是下一行的值。由于 ASI,当 `return`单独出现在一行时,这种情况会一直出现。
function foo() {
  return
    'search your feelings, you know it to be foo'
}

// good
const luke = {};
const leia = {};
[luke, leia].forEach((jedi) => {
  jedi.father = 'vader';
});

// good
const reaction = "No! That’s impossible!";
(async function meanwhileOnTheFalcon() {
  // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
  // ...
}());

// good
function foo() {
  return 'search your feelings, you know it to be foo';
}
[更多](https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214%237365214).

⬆ 返回顶部

类型转换与强制转换

⬆ 返回顶部

命名规范

// —

// 允许但不够语义化 export const apiKey = 'SOMEKEY';

// 在大多数情况下更好 export const API_KEY = 'SOMEKEY';

// —

// bad - 不必要的大写键,没有增加任何语义
export const MAPPING = {
  KEY: 'value' };

// good
export const MAPPING = {
  key: 'value'
};
```

⬆ 返回顶部

Get-Set 访问器

⬆ 返回顶部

事件

⬆ 返回顶部

jQuery

⬆ back to top

ECMAScript 5 兼容性

⬆ 返回顶部

ECMAScript 6+ (ES 2015+) 风格

  1. 箭头函数——Arrow Functions
  2. 类——Classes
  3. 对象缩写——Object Shorthand
  4. 对象简写——Object Concise
  5. 对象计算属性——Object Computed Properties
  6. 模板字符串——Template Strings
  7. 解构赋值——Destructuring
  8. 默认参数——Default Parameters
  9. 剩余参数——Rest
  10. 数组拓展——Array Spreads
  11. Let and Const
  12. 幂操作符——Exponentiation Operator
  13. 迭代器和生成器——Iterators and Generators
  14. 模块——Modules

⬆ 回到顶部

标准库

标准库中包含一些功能受损但是由于历史原因遗留的工具类

测试

⬆ 回到顶部

性能

⬆ back to top

资源

Learning ES6

Read This

Tools

Other Style Guides

Other Styles

Further Reading

Books

Blogs

Podcasts

⬆ back to top

In the Wild

This is a list of organizations that are using this style guide. Send us a pull request and we’ll add you to the list.

⬆ back to top

Translation

This style guide is also available in other languages:

The JavaScript Style Guide Guide

Chat With Us About JavaScript

Contributors

License

(The MIT License)

Copyright (c) 2012 Airbnb

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

⬆ back to top

Amendments

We encourage you to fork this guide and change the rules to fit your team’s style guide. Below, you may list some amendments to the style guide. This allows you to periodically update your style guide without having to deal with merge conflicts.

};