diff --git a/.gitignore b/.gitignore
index ac10dfe528..521b6bbd07 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,5 @@
# gitignore
-
+docs-dist
node_modules
# Only apps should have lockfiles
diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md
new file mode 100644
index 0000000000..6be9230b24
--- /dev/null
+++ b/CONTRIBUTION.md
@@ -0,0 +1,18 @@
+# 贡献指南
+
+## 操作步骤
+### 准备
+- 设置 upstream 源: `git remote add upstream git@github.com:airbnb/javascript.git`
+
+### 文档更新
+> master 用于跟踪upstream
+
+1. git fetch upstream
+1. 对比文件差异
+ 1. `git diff master upstream/master README.md`
+ 2. `git diff master upstream/master react/README.md`
+2. `git checkout cn`,修改 cn 分支下 README.md
+3. master 节点同步到 upstream 最新节点; `git checkout master && git rebase upstream/master`
+
+### 文档发布
+`sh scripts/page.sh` 将 Markdown 文档发布到 gp-pages 分支
\ No newline at end of file
diff --git a/README.md b/README.md
index f28bf24a7c..977a6810b7 100644
--- a/README.md
+++ b/README.md
@@ -1,76 +1,81 @@
-# Airbnb JavaScript Style Guide() {
+# Airbnb JavaScript 风格指南() {
-*A mostly reasonable approach to JavaScript*
+*使用 JavaScript 最合理的方式*。
-> **Note**: this guide assumes you are using [Babel](https://babeljs.io), and requires that you use [babel-preset-airbnb](https://npmjs.com/babel-preset-airbnb) or the equivalent. It also assumes you are installing shims/polyfills in your app, with [airbnb-browser-shims](https://npmjs.com/airbnb-browser-shims) or the equivalent.
+> **注意**: 这个指南假定你正在使用 [Babel](https://babeljs.io),并且需要你使用 [babel-preset-airbnb](https://npmjs.com/babel-preset-airbnb) 或与其等效的预设。同时假定你在你的应用里安装了 带有 [airbnb-browser-shims](https://npmjs.com/airbnb-browser-shims) 或与其等效的插件的 `shims/polyfills`。
[](https://www.npmjs.com/package/eslint-config-airbnb)
[](https://www.npmjs.com/package/eslint-config-airbnb-base)
-[](https://gitter.im/airbnb/javascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
-
-This guide is available in other languages too. See [Translation](#translation)
-
-Other Style Guides
-
- - [ES5 (Deprecated)](https://github.com/airbnb/javascript/tree/es5-deprecated/es5)
- - [React](react/)
- - [CSS-in-JavaScript](css-in-javascript/)
- - [CSS & Sass](https://github.com/airbnb/css)
- - [Ruby](https://github.com/airbnb/ruby)
-
-## Table of Contents
-
- 1. [Types](#types)
- 1. [References](#references)
- 1. [Objects](#objects)
- 1. [Arrays](#arrays)
- 1. [Destructuring](#destructuring)
- 1. [Strings](#strings)
- 1. [Functions](#functions)
- 1. [Arrow Functions](#arrow-functions)
- 1. [Classes & Constructors](#classes--constructors)
- 1. [Modules](#modules)
- 1. [Iterators and Generators](#iterators-and-generators)
- 1. [Properties](#properties)
- 1. [Variables](#variables)
- 1. [Hoisting](#hoisting)
- 1. [Comparison Operators & Equality](#comparison-operators--equality)
- 1. [Blocks](#blocks)
- 1. [Control Statements](#control-statements)
- 1. [Comments](#comments)
- 1. [Whitespace](#whitespace)
- 1. [Commas](#commas)
- 1. [Semicolons](#semicolons)
- 1. [Type Casting & Coercion](#type-casting--coercion)
- 1. [Naming Conventions](#naming-conventions)
- 1. [Accessors](#accessors)
- 1. [Events](#events)
- 1. [jQuery](#jquery)
- 1. [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
- 1. [ECMAScript 6+ (ES 2015+) Styles](#ecmascript-6-es-2015-styles)
- 1. [Standard Library](#standard-library)
- 1. [Testing](#testing)
- 1. [Performance](#performance)
- 1. [Resources](#resources)
- 1. [In the Wild](#in-the-wild)
- 1. [Translation](#translation)
- 1. [The JavaScript Style Guide Guide](#the-javascript-style-guide-guide)
- 1. [Chat With Us About JavaScript](#chat-with-us-about-javascript)
- 1. [Contributors](#contributors)
- 1. [License](#license)
- 1. [Amendments](#amendments)
-
-## Types
-
-
- - [1.1](#types--primitives) **Primitives**: When you access a primitive type you work directly on its value.
-
- - `string`
- - `number`
- - `boolean`
- - `null`
- - `undefined`
- - `symbol`
+[](https://gitter.im/airbnb/javascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
+
+这个指南支持的其他语言翻译版请看 [Translation](#translation)。
+
+其他风格指南:
+ - [ES5 (已废弃)](https://github.com/airbnb/javascript/tree/es5-deprecated/es5)
+ - [React](react/)
+ - [CSS-in-JavaScript](css-in-javascript/)
+ - [CSS & Sass](https://github.com/airbnb/css)
+ - [Ruby](https://github.com/airbnb/ruby)
+
+## 目录
+
+- [Airbnb JavaScript 风格指南() {](#airbnb-javascript-风格指南-)
+ - [目录](#目录)
+ - [类型](#类型)
+ - [引用](#引用)
+ - [对象](#对象)
+ - [数组](#数组)
+ - [解构](#解构)
+ - [字符串](#字符串)
+ - [函数](#函数)
+ - [箭头函数](#箭头函数)
+ - [类与构造函数](#类与构造函数)
+ - [模块](#模块)
+ - [迭代器与生成器](#迭代器与生成器)
+ - [属性](#属性)
+ - [变量](#变量)
+ - [提升](#提升)
+ - [比较运算符与相等](#比较运算符与相等)
+ - [块](#块)
+ - [控制语句](#控制语句)
+ - [注释](#注释)
+ - [空格](#空格)
+ - [逗号](#逗号)
+ - [分号](#分号)
+ - [类型转换与强制转换](#类型转换与强制转换)
+ - [命名规范](#命名规范)
+ - [Get-Set 访问器](#get-set-访问器)
+ - [事件](#事件)
+ - [jQuery](#jquery)
+ - [ECMAScript 5 兼容性](#ecmascript-5-兼容性)
+ - [ECMAScript 6+ (ES 2015+) 风格](#ecmascript-6-es-2015-风格)
+ - [标准库](#标准库)
+ - [测试](#测试)
+ - [性能](#性能)
+ - [资源](#资源)
+ - [In the Wild](#in-the-wild)
+ - [Translation](#translation)
+ - [The JavaScript Style Guide Guide](#the-javascript-style-guide-guide)
+ - [Chat With Us About JavaScript](#chat-with-us-about-javascript)
+ - [Contributors](#contributors)
+ - [License](#license)
+ - [Amendments](#amendments)
+- [};](#)
+
+## 类型
+
+
+
+
+ - [1.1](#types--primitives) 基本类型: 你可以直接获取到基本类型的值
+
+ + `string`
+ + `number`
+ + `boolean`
+ + `null`
+ + `undefined`
+ + `symbol`
+ + `bigint`
```javascript
const foo = 1;
@@ -80,15 +85,16 @@ Other Style Guides
console.log(foo, bar); // => 1, 9
```
+ + 由于 Symbols 和 BigInts 不能被正确的 polyfill。所以不应在不能原生支持这些类型的环境或浏览器中使用他们。
- - Symbols cannot be faithfully polyfilled, so they should not be used when targeting browsers/environments that don’t support them natively.
+
+
-
- - [1.2](#types--complex) **Complex**: When you access a complex type you work on a reference to its value.
+ - [1.2](#types--complex) 复杂类型: 复杂类型赋值是获取到他的引用的值。
- - `object`
- - `array`
- - `function`
+ + `object`
+ + `array`
+ + `function`
```javascript
const foo = [1, 2];
@@ -99,14 +105,16 @@ Other Style Guides
console.log(foo[0], bar[0]); // => 9, 9
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 回到顶部](#目录)**
-## References
+## 引用
-
- - [2.1](#references--prefer-const) Use `const` for all of your references; avoid using `var`. eslint: [`prefer-const`](https://eslint.org/docs/rules/prefer-const.html), [`no-const-assign`](https://eslint.org/docs/rules/no-const-assign.html)
+
+
- > Why? This ensures that you can’t reassign your references, which can lead to bugs and difficult to comprehend code.
+ - [2.1](#references--prefer-const) 所有的赋值都用 `const`,避免使用 `var`。eslint: [`prefer-const`](http://eslint.org/docs/rules/prefer-const), [`no-const-assign`](http://eslint.org/docs/rules/no-const-assign)
+
+ > 为什么?因为这个能确保你不会改变你的初始值,重复引用会导致 bug 并且使代码变得难以理解。
```javascript
// bad
@@ -118,10 +126,12 @@ Other Style Guides
const b = 2;
```
-
- - [2.2](#references--disallow-var) If you must reassign references, use `let` instead of `var`. eslint: [`no-var`](https://eslint.org/docs/rules/no-var.html)
+
+
+
+ - [2.2](#references--disallow-var) 如果你一定要对参数重新赋值,使用 `let`,而不是 `var`。eslint: [`no-var`](http://eslint.org/docs/rules/no-var)
- > Why? `let` is block-scoped rather than function-scoped like `var`.
+ > 为什么?因为 `let` 是块级作用域,而 `var` 是函数级作用域。
```javascript
// bad
@@ -137,25 +147,31 @@ Other Style Guides
}
```
-
- - [2.3](#references--block-scope) Note that both `let` and `const` are block-scoped.
+
+
+ - [2.3](#references--block-scope) 注意:`let` 和 `const` 都是块级作用域, 而 `var` 是函数级作用域
```javascript
- // const and let only exist in the blocks they are defined in.
+ // const 和 let 都只存在于它被定义的那个块级作用域。
{
let a = 1;
const b = 1;
+ var c = 1;
}
- console.log(a); // ReferenceError
- console.log(b); // ReferenceError
+ console.log(a); // 引用错误
+ console.log(b); // 引用错误
+ console.log(c); // 打印 1
```
-**[⬆ back to top](#table-of-contents)**
+ 上面的代码里,`a` 和 `b` 的定义会报引用错误,这是因为 `a` 和 `b` 是块级作用域, 而 `c` 的作用域是在函数里的。
+
+**[⬆ 返回顶部](#目录)**
-## Objects
+## 对象
-
- - [3.1](#objects--no-new) Use the literal syntax for object creation. eslint: [`no-new-object`](https://eslint.org/docs/rules/no-new-object.html)
+
+
+ - [3.1](#objects--no-new) 使用字面值创建对象。eslint: [`no-new-object`](http://eslint.org/docs/rules/no-new-object)
```javascript
// bad
@@ -165,10 +181,12 @@ Other Style Guides
const item = {};
```
-
- - [3.2](#es6-computed-properties) Use computed property names when creating objects with dynamic property names.
+
+
- > Why? They allow you to define all the properties of an object in one place.
+ - [3.2](#es6-computed-properties) 使用计算属性名创建一个带有动态属性名的对象。
+
+ > 为什么?因为这可以使你在同一个地方定义所有对象属性。
```javascript
@@ -191,8 +209,10 @@ Other Style Guides
};
```
-
- - [3.3](#es6-object-shorthand) Use object method shorthand. eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html)
+
+
+
+ - [3.3](#es6-object-shorthand) 用对象方法简写。eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand)
```javascript
// bad
@@ -208,16 +228,18 @@ Other Style Guides
const atom = {
value: 1,
+ // 对象的方法
addValue(value) {
return atom.value + value;
},
};
```
-
- - [3.4](#es6-object-concise) Use property value shorthand. eslint: [`object-shorthand`](https://eslint.org/docs/rules/object-shorthand.html)
+
+
+ - [3.4](#es6-object-concise) 用属性值缩写。eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand)
- > Why? It is shorter to write and descriptive.
+ > 为什么?这样写更简洁,且可读性更高。
```javascript
const lukeSkywalker = 'Luke Skywalker';
@@ -233,10 +255,12 @@ Other Style Guides
};
```
-
- - [3.5](#objects--grouped-shorthand) Group your shorthand properties at the beginning of your object declaration.
+
+
- > Why? It’s easier to tell which properties are using the shorthand.
+ - [3.5](#objects--grouped-shorthand) 将你的所有缩写放在对象声明的前面。
+
+ > 为什么?因为这样能更方便地知道有哪些属性用了缩写。
```javascript
const anakinSkywalker = 'Anakin Skywalker';
@@ -263,10 +287,12 @@ Other Style Guides
};
```
-
- - [3.6](#objects--quoted-props) Only quote properties that are invalid identifiers. eslint: [`quote-props`](https://eslint.org/docs/rules/quote-props.html)
+
+
+
+ - [3.6](#objects--quoted-props) 只对那些无效的标示使用引号 `''`。eslint: [`quote-props`](http://eslint.org/docs/rules/quote-props)
- > Why? In general we consider it subjectively easier to read. It improves syntax highlighting, and is also more easily optimized by many JS engines.
+ > 为什么?通常我们认为这种方式主观上更易读。不仅优化了代码高亮,而且也更容易被许多 JS 引擎优化。
```javascript
// bad
@@ -284,10 +310,12 @@ Other Style Guides
};
```
+
- - [3.7](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`.
+ - [3.7](#objects--prototype-builtins) 不要直接调用 `Object.prototype`上的方法,如 `hasOwnProperty`、`propertyIsEnumerable`、`isPrototypeOf`。eslint: [`no-prototype-builtins`](htt
+ps://eslint.org/docs/rules/no-prototype-builtins)
- > Why? These methods may be shadowed by properties on the object in question - consider `{ hasOwnProperty: false }` - or, the object may be a null object (`Object.create(null)`).
+ > 为什么?在一些有问题的对象上,这些方法可能会被屏蔽掉,如:`{ hasOwnProperty: false }` 或空对象 `Object.create(null)`。 在支持 ES2022 的现代浏览器中,或者被做过类似 的兼容情况下, `Object.hasOwn` 也会被用作 `Object.prototype.hasOwnProperty.call` 的替代品。
```javascript
// bad
@@ -296,40 +324,53 @@ Other Style Guides
// good
console.log(Object.prototype.hasOwnProperty.call(object, key));
+ // better
+ const has = Object.prototype.hasOwnProperty; // 在模块作用域内做一次缓存。
+ console.log(has.call(object, key));
+
// best
- const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
+ console.log(Object.hasOwn(object, key)); // 只能在支持 ES2022 的浏览器中使用
+
/* or */
import has from 'has'; // https://www.npmjs.com/package/has
- // ...
- console.log(has.call(object, key));
+ console.log(has(object, key));
+ /* or */
+ console.log(Object.hasOwn(object, key)); // https://www.npmjs.com/package/object.hasown
```
+
- - [3.8](#objects--rest-spread) Prefer the object spread operator over [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) to shallow-copy objects. Use the object rest operator to get a new object with certain properties omitted.
- ```javascript
- // very bad
- const original = { a: 1, b: 2 };
- const copy = Object.assign(original, { c: 3 }); // this mutates `original` ಠ_ಠ
- delete copy.a; // so does this
+ - [3.8](#objects--rest-spread) 对象浅拷贝时,更推荐使用扩展运算符(即 `...` 运算符),而不是 [`Object.assign`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign)。获取对象指定的几个属性时,用对象的 rest 解构运算符(即 `...` 运算符)更好。eslint: [`prefer-object-spread`](https://eslint.org/docs/rules/prefer-object-spread)
+ + 这一段不太好翻译出来, 大家看下面的例子就懂了。^.^
- // bad
- const original = { a: 1, b: 2 };
- const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
+ ```javascript
+ // very bad
+ const original = { a: 1, b: 2 };
+ const copy = Object.assign(original, { c: 3 }); // 改了 `original` ಠ_ಠ
+ delete copy.a; // so does this
- // good
- const original = { a: 1, b: 2 };
- const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
+ // bad
+ const original = { a: 1, b: 2 };
+ const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
- const { a, ...noA } = copy; // noA => { 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](#table-of-contents)**
+## 数组
-## Arrays
+
+
-
- - [4.1](#arrays--literals) Use the literal syntax for array creation. eslint: [`no-array-constructor`](https://eslint.org/docs/rules/no-array-constructor.html)
+ - [4.1](#arrays--literals) 用字面量创建数组。eslint: [`no-array-constructor`](http://eslint.org/docs/rules/no-array-constructor)
```javascript
// bad
@@ -339,8 +380,9 @@ Other Style Guides
const items = [];
```
-
- - [4.2](#arrays--push) Use [Array#push](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/push) instead of direct assignment to add items to an array.
+
+
+ - [4.2](#arrays--push) 用 [Array#push](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/push) 代替直接向数组中添加一个值。
```javascript
const someStack = [];
@@ -352,8 +394,9 @@ Other Style Guides
someStack.push('abracadabra');
```
-
- - [4.3](#es6-array-spreads) Use array spreads `...` to copy arrays.
+
+
+ - [4.3](#es6-array-spreads) 用扩展运算符做数组浅拷贝,类似上面的对象浅拷贝。
```javascript
// bad
@@ -371,7 +414,8 @@ Other Style Guides
- - [4.4](#arrays--from-iterable) To convert an iterable object to an array, use spreads `...` instead of [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from).
+
+ - [4.4](#arrays--from-iterable) 用 `...` 运算符而不是 [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) 来将一个可迭代的对象转换成数组。
```javascript
const foo = document.querySelectorAll('.foo');
@@ -384,7 +428,7 @@ Other Style Guides
```
- - [4.5](#arrays--from-array-like) Use [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) for converting an array-like object to an array.
+ - [4.5](#arrays--from-array-like) 用 [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) 将一个类数组对象转成一个数组。
```javascript
const arrLike = { 0: 'foo', 1: 'bar', 2: 'baz', length: 3 };
@@ -396,8 +440,10 @@ Other Style Guides
const arr = Array.from(arrLike);
```
+
- - [4.6](#arrays--mapping) Use [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) instead of spread `...` for mapping over iterables, because it avoids creating an intermediate array.
+
+ - [4.6](#arrays--mapping) 用 [`Array.from`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/from) 而不是 `...` 运算符去做 map 遍历。 因为这样可以避免创建一个临时数组。
```javascript
// bad
@@ -407,8 +453,10 @@ Other Style Guides
const baz = Array.from(foo, bar);
```
-
- - [4.7](#arrays--callback-return) Use return statements in array method callbacks. It’s ok to omit the return if the function body consists of a single statement returning an expression without side effects, following [8.2](#arrows--implicit-return). eslint: [`array-callback-return`](https://eslint.org/docs/rules/array-callback-return)
+
+
+
+ - [4.7](#arrays--callback-return) 在数组方法的回调函数中使用 return 语句。如果函数体由一条返回一个表达式的语句组成,并且这个表达式没有副作用, 这个时候可以忽略 return,详见 [8.2](#arrows--implicit-return)。eslint: [`array-callback-return`](http://eslint.org/docs/rules/array-callback-return)
```javascript
// good
@@ -417,19 +465,17 @@ Other Style Guides
return x * y;
});
- // good
- [1, 2, 3].map(x => x + 1);
+ // good 函数只有一个语句
+ [1, 2, 3].map((x) => x + 1);
- // bad - no returned value means `acc` becomes undefined after the first iteration
+ // bad - 没有返回值, 因为在第一次迭代后 acc 就变成 undefined 了
[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
const flatten = acc.concat(item);
- acc[index] = flatten;
});
// good
[[0, 1], [2, 3], [4, 5]].reduce((acc, item, index) => {
const flatten = acc.concat(item);
- acc[index] = flatten;
return flatten;
});
@@ -454,8 +500,9 @@ Other Style Guides
});
```
+
- - [4.8](#arrays--bracket-newline) Use line breaks after open and before close array brackets if an array has multiple lines
+ - [4.8](#arrays--bracket-newline) 如果一个数组有很多行,在数组的 `[` 后和 `]` 前断行。请看下面示例:
```javascript
// bad
@@ -491,14 +538,15 @@ Other Style Guides
];
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Destructuring
+## 解构
-
- - [5.1](#destructuring--object) Use object destructuring when accessing and using multiple properties of an object. eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)
+
+
+ - [5.1](#destructuring--object) 用对象的解构赋值来获取和使用对象某个或多个属性值。eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)
- > Why? Destructuring saves you from creating temporary references for those properties.
+ > 为什么? 解构使您不必为这些属性创建临时引用,并且避免重复引用对象。重复引用对象将造成代码重复、增加阅读次数、提高犯错概率。在一个块级作用域里,解构对象可以在同一个地方给解构字段赋值,而不需要读整个的代码块看它到底用了哪些字段。
```javascript
// bad
@@ -521,8 +569,10 @@ Other Style Guides
}
```
-
- - [5.2](#destructuring--array) Use array destructuring. eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)
+
+
+
+ - [5.2](#destructuring--array) 用数组解构。eslint: [`prefer-destructuring`](https://eslint.org/docs/rules/prefer-destructuring)
```javascript
const arr = [1, 2, 3, 4];
@@ -535,74 +585,79 @@ Other Style Guides
const [first, second] = arr;
```
-
- - [5.3](#destructuring--object-over-array) Use object destructuring for multiple return values, not array destructuring.
+
+
+ - [5.3](#destructuring--object-over-array) 多个返回值用对象的解构,而不是数组解构。
- > Why? You can add new properties over time or change the order of things without breaking call sites.
+ > 为什么?你可以在后期添加新的属性或者变换变量的顺序而不会破坏原有的引用。
```javascript
// bad
function processInput(input) {
- // then a miracle occurs
+ // 然后就是见证奇迹的时刻
return [left, right, top, bottom];
}
- // the caller needs to think about the order of return data
+ // 调用者需要想一想返回值的顺序
const [left, __, top] = processInput(input);
// good
function processInput(input) {
- // then a miracle occurs
+ // oops,奇迹又发生了
return { left, right, top, bottom };
}
- // the caller selects only the data they need
+ // 调用者只需要选择他想用的值就好了
const { left, top } = processInput(input);
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ back to top](#目录)**
-## Strings
+## 字符串
-
- - [6.1](#strings--quotes) Use single quotes `''` for strings. eslint: [`quotes`](https://eslint.org/docs/rules/quotes.html)
+
+
+ - [6.1](#strings--quotes) 字符串应使用单引号 `''` 。eslint: [`quotes`](https://eslint.org/docs/rules/quotes)
```javascript
// bad
const name = "Capt. Janeway";
- // bad - template literals should contain interpolation or newlines
+ // bad - 模板字符串应该包含插入文字或换行
const name = `Capt. Janeway`;
// good
const name = 'Capt. Janeway';
```
-
- - [6.2](#strings--line-length) Strings that cause the line to go over 100 characters should not be written across multiple lines using string concatenation.
+
+
+
+ - [6.2](#strings--line-length) 超过 100 个字符的字符串不应该用字符串连接成多行。
- > Why? Broken strings are painful to work with and make code less searchable.
+ > 为什么?字符串折行增加编写难度且不易被搜索。
```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 \
+ 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.';
+ '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.';
```
-
- - [6.3](#es6-template-literals) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](https://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](https://eslint.org/docs/rules/template-curly-spacing)
+
+
+ - [6.3](#es6-template-literals) 当需要动态生成字符串时,使用模板字符串而不是字符串拼接。eslint: [`prefer-template`](https://eslint.org/docs/rules/prefer-template) [`template-curly-spacing`](https://eslint.org/docs/rules/template-curly-spacing)
- > Why? Template strings give you a readable, concise syntax with proper newlines and string interpolation features.
+ > 为什么?模板字符串更具可读性、多行语法更简洁以及更方便插入变量到字符串里头。
```javascript
// bad
@@ -626,13 +681,17 @@ Other Style Guides
}
```
-
- - [6.4](#strings--eval) Never use `eval()` on a string, it opens too many vulnerabilities. eslint: [`no-eval`](https://eslint.org/docs/rules/no-eval)
+
+
+ - [6.4](#strings--eval) 永远不要使用 `eval()`,该方法有太多漏洞。eslint: [`no-eval`](https://eslint.org/docs/rules/no-eval)
+
+
- - [6.5](#strings--escaping) Do not unnecessarily escape characters in strings. eslint: [`no-useless-escape`](https://eslint.org/docs/rules/no-useless-escape)
- > Why? Backslashes harm readability, thus they should only be present when necessary.
+ - [6.5](#strings--escaping) 不要使用不必要的转义字符。eslint: [`no-useless-escape`](http://eslint.org/docs/rules/no-useless-escape)
+
+ > 为什么?反斜线可读性差,因此仅当必要时才使用它。
```javascript
// bad
@@ -640,17 +699,28 @@ Other Style Guides
// good
const foo = '\'this\' is "quoted"';
+
+ //best
const foo = `my name is '${name}'`;
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
+
+
+## 函数
-## Functions
+
+
-
- - [7.1](#functions--declarations) Use named function expressions instead of function declarations. eslint: [`func-style`](https://eslint.org/docs/rules/func-style)
+ - [7.1](#functions--declarations) 使用命名函数表达式而不是函数声明。eslint: [`func-style`](http://eslint.org/docs/rules/func-style) [`func-names`](https://eslint.org/docs/latest/rules/func-names)
- > Why? Function declarations are hoisted, which means that it’s easy - too easy - to reference the function before it is defined in the file. This harms readability and maintainability. If you find that a function’s definition is large or complex enough that it is interfering with understanding the rest of the file, then perhaps it’s time to extract it to its own module! Don’t forget to explicitly name the expression, regardless of whether or not the name is inferred from the containing variable (which is often the case in modern browsers or when using compilers such as Babel). This eliminates any assumptions made about the Error’s call stack. ([Discussion](https://github.com/airbnb/javascript/issues/794))
+ > 函数表达式: const func = function () {}
+
+ > 函数声明: function func() {}
+
+ > 为什么?函数声明会发生提升,这意味着在一个文件里函数很容易在其被定义之前就被引用了。这样伤害了代码可读性和可维护性。如果你发现一个函数又大又复杂,且这个函数妨碍了这个文件其他部分的理解性,你应当单独把这个函数提取成一个单独的模块。不管这个名字是不是由一个确定的变量推断出来的,别忘了给表达式清晰的命名(这在现代浏览器和类似 babel 编译器中很常见)。这消除了由匿名函数在错误调用栈产生的所有假设。 ([讨论](https://github.com/airbnb/javascript/issues/794))
+
+ > 译者注:这一段可能不是很好理解,简单来说就是使用函数声明会发生提升(即在函数被声明之前就可以使用);使用匿名函数会导致报错难以定位错误。[常见错误范例](https://github.com/lin-123/javascript/issues/26) [这一段英文原文在这](https://github.com/airbnb/javascript#functions)。
```javascript
// bad
@@ -665,15 +735,19 @@ Other Style Guides
// good
// lexical name distinguished from the variable-referenced invocation(s)
+ // 函数表达式名和声明的函数名是不一样的
const short = function longUniqueMoreDescriptiveLexicalFoo() {
// ...
};
```
-
- - [7.2](#functions--iife) Wrap immediately invoked function expressions in parentheses. eslint: [`wrap-iife`](https://eslint.org/docs/rules/wrap-iife.html)
+
+
+ - [7.2](#functions--iife) 把立即执行函数包裹在圆括号里。eslint: [`wrap-iife`](http://eslint.org/docs/rules/wrap-iife)
- > Why? An immediately invoked function expression is a single unit - wrapping both it, and its invocation parens, in parens, cleanly expresses this. Note that in a world with modules everywhere, you almost never need an IIFE.
+ > 立即执行函数:Immediately Invoked Function expression = IIFE。
+ > 为什么?一个立即调用的函数表达式是一个单元 - 把它和它的调用者(圆括号)包裹起来,使代码读起来更清晰。
+ > 另外,在模块化世界里,你几乎用不着 IIFE。
```javascript
// immediately-invoked function expression (IIFE)
@@ -682,11 +756,15 @@ Other Style Guides
}());
```
-
- - [7.3](#functions--in-blocks) Never declare a function in a non-function block (`if`, `while`, etc). Assign the function to a variable instead. Browsers will allow you to do it, but they all interpret it differently, which is bad news bears. eslint: [`no-loop-func`](https://eslint.org/docs/rules/no-loop-func.html)
+
+
+
+ - [7.3](#functions--in-blocks) 不要在非函数块(`if`、`while` 等)内声明函数。把这个函数分配给一个变量。浏览器会允许你这样做,但不同浏览器的解析方式不同,这是一个坏消息。eslint: [`no-loop-func`](http://eslint.org/docs/rules/no-loop-func)
-
- - [7.4](#functions--note-on-blocks) **Note:** ECMA-262 defines a `block` as a list of statements. A function declaration is not a statement.
+
+
+
+ - [7.4](#functions--note-on-blocks) **注意**:ECMA-262 中对块(`block`)的定义是: 一系列的语句。但是函数声明不是一个语句, 函数表达式是一个语句。
```javascript
// bad
@@ -705,8 +783,9 @@ Other Style Guides
}
```
-
- - [7.5](#functions--arguments-shadow) Never name a parameter `arguments`. This will take precedence over the `arguments` object that is given to every function scope.
+
+
+ - [7.5](#functions--arguments-shadow) 不要用 `arguments` 命名参数。他的优先级高于每个函数作用域自带的 `arguments` 对象,这会导致函数自带的 `arguments` 值被覆盖。
```javascript
// bad
@@ -720,10 +799,12 @@ Other Style Guides
}
```
-
- - [7.6](#es6-rest) Never use `arguments`, opt to use rest syntax `...` instead. eslint: [`prefer-rest-params`](https://eslint.org/docs/rules/prefer-rest-params)
+
+
+
+ - [7.6](#es6-rest) 不要使用 `arguments`,用收集参数语法 `...` 代替。eslint: [`prefer-rest-params`](http://eslint.org/docs/rules/prefer-rest-params)
- > Why? `...` is explicit about which arguments you want pulled. Plus, rest arguments are a real Array, and not merely Array-like like `arguments`.
+ > 为什么?`...` 明确你想用哪个参数。而且收集参数是真数组,而不是类似数组的 `arguments`。
```javascript
// bad
@@ -738,15 +819,17 @@ Other Style Guides
}
```
-
- - [7.7](#es6-default-parameters) Use default parameter syntax rather than mutating function arguments.
+
+
+
+ - [7.7](#es6-default-parameters) 用默认参数语法而不是在函数里对参数重新赋值。
```javascript
// really bad
function handleThings(opts) {
- // No! We shouldn’t mutate function arguments.
- // Double bad: if opts is falsy it'll be set to an object which may
- // be what you want but it can introduce subtle bugs.
+ // 不!我们不该修改 arguments
+ // 第二:如果 opts 的值为 false, 它会被赋值为 {}
+ // 虽然你想这么写,但是这个会带来一些微妙的 bug。
opts = opts || {};
// ...
}
@@ -765,10 +848,12 @@ Other Style Guides
}
```
-
- - [7.8](#functions--default-side-effects) Avoid side effects with default parameters.
+
+
- > Why? They are confusing to reason about.
+ - [7.8](#functions--default-side-effects) 避免默认参数的副作用。
+
+ > 为什么?他会令人迷惑不解,比如下面这个,a 到底等于几,这个需要想一下。
```javascript
var b = 1;
@@ -782,8 +867,9 @@ Other Style Guides
count(); // 3
```
-
- - [7.9](#functions--defaults-last) Always put default parameters last.
+
+
+ - [7.9](#functions--defaults-last) 把默认参数赋值放在最后。eslint: [`default-param-last`](https://eslint.org/docs/rules/default-param-last)
```javascript
// bad
@@ -797,23 +883,26 @@ Other Style Guides
}
```
-
- - [7.10](#functions--constructor) Never use the Function constructor to create a new function. eslint: [`no-new-func`](https://eslint.org/docs/rules/no-new-func)
+
+
+
+ - [7.10](#functions--constructor) 不要用函数构造器创建函数。eslint: [`no-new-func`](http://eslint.org/docs/rules/no-new-func)
- > Why? Creating a function in this way evaluates a string similarly to `eval()`, which opens vulnerabilities.
+ > 为什么?以这种方式创建函数将类似于字符串 eval(),存在漏洞。
```javascript
// bad
- var add = new Function('a', 'b', 'return a + b');
+ const add = new Function('a', 'b', 'return a + b');
// still bad
- var subtract = Function('a', 'b', 'return a - b');
+ const subtract = Function('a', 'b', 'return a - b');
```
-
- - [7.11](#functions--signature-spacing) Spacing in a function signature. eslint: [`space-before-function-paren`](https://eslint.org/docs/rules/space-before-function-paren) [`space-before-blocks`](https://eslint.org/docs/rules/space-before-blocks)
+
+
+ - [7.11](#functions--signature-spacing) 函数定义部分要有空格。eslint: [`space-before-function-paren`](http://eslint.org/docs/rules/space-before-function-paren) [`space-before-blocks`](http://eslint.org/docs/rules/space-before-blocks)
- > Why? Consistency is good, and you shouldn’t have to add or remove a space when adding or removing a name.
+ > 为什么?统一性好,而且在你添加/删除一个名字的时候不需要添加/删除空格。
```javascript
// bad
@@ -826,27 +915,30 @@ Other Style Guides
const y = function a() {};
```
-
- - [7.12](#functions--mutate-params) Never mutate parameters. eslint: [`no-param-reassign`](https://eslint.org/docs/rules/no-param-reassign.html)
+
+
- > Why? Manipulating objects passed in as parameters can cause unwanted variable side effects in the original caller.
+ - [7.12](#functions--mutate-params) 不要修改参数. eslint: [`no-param-reassign`](http://eslint.org/docs/rules/no-param-reassign)
+
+ > 为什么?操作参数对象对原始调用者会导致意想不到的副作用。就是不要改参数的数据结构,保留参数原始值和数据结构。
```javascript
// bad
function f1(obj) {
obj.key = 1;
- }
+ };
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
- }
+ };
```
-
- - [7.13](#functions--reassign-params) Never reassign parameters. eslint: [`no-param-reassign`](https://eslint.org/docs/rules/no-param-reassign.html)
+
+
+ - [7.13](#functions--reassign-params) 不要对参数重新赋值。eslint: [`no-param-reassign`](http://eslint.org/docs/rules/no-param-reassign)
- > Why? Reassigning parameters can lead to unexpected behavior, especially when accessing the `arguments` object. It can also cause optimization issues, especially in V8.
+ > 为什么?参数重新赋值会导致意外行为,尤其是对 `arguments`。这也会导致优化问题,特别是在 V8 引擎里。
```javascript
// bad
@@ -871,10 +963,12 @@ Other Style Guides
}
```
-
- - [7.14](#functions--spread-vs-apply) Prefer the use of the spread operator `...` to call variadic functions. eslint: [`prefer-spread`](https://eslint.org/docs/rules/prefer-spread)
+
+
+
+ - [7.14](#functions--spread-vs-apply) 使用拓展运算符调用多参数的函数。eslint: [`prefer-spread`](http://eslint.org/docs/rules/prefer-spread)
- > Why? It’s cleaner, you don’t need to supply a context, and you can not easily compose `new` with `apply`.
+ > 为什么?这样更清晰,你不必提供上下文(即指定 this 值),而且你不能轻易地用 `apply` 来组成 `new`。
```javascript
// bad
@@ -892,8 +986,9 @@ Other Style Guides
new Date(...[2016, 8, 5]);
```
+
- - [7.15](#functions--signature-invocation-indentation) Functions with multiline signatures, or invocations, should be indented just like every other multiline list in this guide: with each item on a line by itself, with a trailing comma on the last item. eslint: [`function-paren-newline`](https://eslint.org/docs/rules/function-paren-newline)
+ - [7.15](#functions--signature-invocation-indentation) 调用或者编写一个包含多个参数的函数的缩进,应该像这个指南里的其他多行代码写法一样——即每行只包含一个参数,每行逗号结尾。
```javascript
// bad
@@ -903,7 +998,7 @@ Other Style Guides
// ...
}
- // good
+ // good 缩进不要太过分
function foo(
bar,
baz,
@@ -925,16 +1020,18 @@ Other Style Guides
);
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Arrow Functions
+## 箭头函数
-
- - [8.1](#arrows--use-them) When you must use an anonymous function (as when passing an inline callback), use arrow function notation. eslint: [`prefer-arrow-callback`](https://eslint.org/docs/rules/prefer-arrow-callback.html), [`arrow-spacing`](https://eslint.org/docs/rules/arrow-spacing.html)
+
+
- > Why? It creates a version of the function that executes in the context of `this`, which is usually what you want, and is a more concise syntax.
+ - [8.1](#arrows--use-them) 当你一定要用函数表达式(在回调函数里)的时候,使用箭头函数。 eslint: [`prefer-arrow-callback`](http://eslint.org/docs/rules/prefer-arrow-callback), [`arrow-spacing`](http://eslint.org/docs/rules/arrow-spacing)
- > Why not? If you have a fairly complicated function, you might move that logic out into its own named function expression.
+ > 为什么?箭头函数中的 `this` 与定义该函数的上下文中的 `this` 一致,这通常才是你想要的。而且箭头函数是更简洁的语法。
+
+ > 什么时候不用箭头函数:如果你的函数逻辑较复杂,你应该把它单独写入一个命名函数里头。
```javascript
// bad
@@ -950,20 +1047,21 @@ Other Style Guides
});
```
-
- - [8.2](#arrows--implicit-return) If the function body consists of a single statement returning an [expression](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) without side effects, omit the braces and use the implicit return. Otherwise, keep the braces and use a `return` statement. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html), [`arrow-body-style`](https://eslint.org/docs/rules/arrow-body-style.html)
+
+
+ - [8.2](#arrows--implicit-return) 如果函数体由一个没有副作用的 [表达式](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions) 语句组成,删除大括号和 return。否则,使用大括号和 `return` 语句。 eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens), [`arrow-body-style`](https://eslint.org/docs/rules/arrow-body-style)
- > Why? Syntactic sugar. It reads well when multiple functions are chained together.
+ > 为什么?语法糖,当多个函数链在一起的时候好读。
```javascript
- // bad
- [1, 2, 3].map(number => {
+ // bad map 没有 return
+ [1, 2, 3].map((number) => {
const nextNumber = number + 1;
`A string containing the ${nextNumber}.`;
});
// good
- [1, 2, 3].map(number => `A string containing the ${number}.`);
+ [1, 2, 3].map((number) => `A string containing the ${number + 1}.`);
// good
[1, 2, 3].map((number) => {
@@ -976,11 +1074,11 @@ Other Style Guides
[index]: number,
}));
- // No implicit return with side effects
+ // 没有明显的存在副作用的 return 语句
function foo(callback) {
const val = callback();
if (val === true) {
- // Do something if callback returns true
+ // 当 callback 返回 true 时在这里执行
}
}
@@ -989,51 +1087,62 @@ Other Style Guides
// bad
foo(() => bool = true);
+
// good
foo(() => {
bool = true;
});
```
-
- - [8.3](#arrows--paren-wrap) In case the expression spans over multiple lines, wrap it in parentheses for better readability.
+
+
- > Why? It shows clearly where the function starts and ends.
+ - [8.3](#arrows--paren-wrap) 如果表达式涉及多行,把他包裹在圆括号里以提高可读性。
- ```javascript
+ > 为什么?这样能清晰地显示函数的开始位置和结束位置。
+
+ ```js
// bad
- ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
+ ['get', 'post', 'put'].map((httpMethod) => Object.prototype.hasOwnProperty.call(
httpMagicObjectWithAVeryLongName,
- httpMethod,
+ httpMethod
)
);
// good
- ['get', 'post', 'put'].map(httpMethod => (
+ ['get', 'post', 'put'].map((httpMethod) => (
Object.prototype.hasOwnProperty.call(
httpMagicObjectWithAVeryLongName,
- httpMethod,
+ httpMethod
)
));
```
-
- - [8.4](#arrows--one-arg-parens) If your function takes a single argument and doesn’t use braces, omit the parentheses. Otherwise, always include parentheses around arguments for clarity and consistency. Note: it is also acceptable to always use parentheses, in which case use the [“always” option](https://eslint.org/docs/rules/arrow-parens#always) for eslint. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens.html)
+
+
- > Why? Less visual clutter.
+ - [8.4](#arrows--one-arg-parens) 在箭头函数参数两头,总是使用小括号包裹住参数,这样做使代码更清晰且一致. eslint: [`arrow-parens`](https://eslint.org/docs/rules/arrow-parens)
- ```javascript
- // bad
- [1, 2, 3].map((x) => x * x);
+ > 为什么?当你想要添加或删除参数时改动最小。
- // good
+ ```js
+ // bad
[1, 2, 3].map(x => x * x);
// good
+ [1, 2, 3].map((x) => x * x);
+
+ // bad
[1, 2, 3].map(number => (
`A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
));
+ // good
+ [1, 2, 3].map((number) => (
+ `A long string with the ${number}. It’s so long that we don’t want it to take up space on the .map line!`
+ ));
+
+
// bad
[1, 2, 3].map(x => {
const y = x + 1;
@@ -1047,28 +1156,32 @@ Other Style Guides
});
```
-
- - [8.5](#arrows--confusing) Avoid confusing arrow function syntax (`=>`) with comparison operators (`<=`, `>=`). eslint: [`no-confusing-arrow`](https://eslint.org/docs/rules/no-confusing-arrow)
+
+
- ```javascript
+ - [8.5](#arrows--confusing) 避免箭头函数(`=>`)和比较操作符(`<=`, `>=`)混淆. eslint: [`no-confusing-arrow`](http://eslint.org/docs/rules/no-confusing-arrow)
+
+ ```js
// bad
- const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
+ const itemHeight = (item) => item.height <= 256 ? item.largeSize : item.smallSize;
// bad
- const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
+ const itemHeight = (item) => item.height >= 256 ? item.largeSize : item.smallSize;
// good
- const itemHeight = item => (item.height > 256 ? item.largeSize : item.smallSize);
+ const itemHeight = (item) => (item.height <= 256 ? item.largeSize : item.smallSize);
// good
const itemHeight = (item) => {
const { height, largeSize, smallSize } = item;
- return height > 256 ? largeSize : smallSize;
+ return height <= 256 ? largeSize : smallSize;
};
```
+
- - [8.6](#whitespace--implicit-arrow-linebreak) Enforce the location of arrow function bodies with implicit returns. eslint: [`implicit-arrow-linebreak`](https://eslint.org/docs/rules/implicit-arrow-linebreak)
+
+ - [8.6](#whitespace--implicit-arrow-linebreak) 使箭头函数体有一个清晰的返回。 eslint: [`implicit-arrow-linebreak`](https://eslint.org/docs/rules/implicit-arrow-linebreak)
```javascript
// bad
@@ -1086,14 +1199,16 @@ Other Style Guides
)
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
+
-## Classes & Constructors
+## 类与构造函数
-
- - [9.1](#constructors--use-class) Always use `class`. Avoid manipulating `prototype` directly.
+
+
+ - [9.1](#constructors--use-class) 使用 `class` 语法。避免直接操作 `prototype`。
- > Why? `class` syntax is more concise and easier to reason about.
+ > 为什么?`class` 语法更简洁更易理解。
```javascript
// bad
@@ -1119,10 +1234,12 @@ Other Style Guides
}
```
-
- - [9.2](#constructors--extends) Use `extends` for inheritance.
+
+
- > Why? It is a built-in way to inherit prototype functionality without breaking `instanceof`.
+ - [9.2](#constructors--extends) 用 `extends` 实现继承。
+
+ > 为什么?它是一种内置的方法来继承原型功能而不破坏 `instanceof`。
```javascript
// bad
@@ -1133,7 +1250,7 @@ Other Style Guides
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function () {
return this.queue[0];
- };
+ }
// good
class PeekableQueue extends Queue {
@@ -1143,8 +1260,9 @@ Other Style Guides
}
```
-
- - [9.3](#constructors--chaining) Methods can return `this` to help with method chaining.
+
+
+ - [9.3](#constructors--chaining) 方法可以返回 `this` 来实现链式调用。
```javascript
// bad
@@ -1180,8 +1298,10 @@ Other Style Guides
.setHeight(20);
```
-
- - [9.4](#constructors--tostring) It’s okay to write a custom `toString()` method, just make sure it works successfully and causes no side effects.
+
+
+
+ - [9.4](#constructors--tostring) 自己写 `toString()` 方法是可以的,但需要保证它可以正常工作且没有副作用。
```javascript
class Jedi {
@@ -1199,8 +1319,9 @@ Other Style Guides
}
```
-
- - [9.5](#constructors--no-useless) Classes have a default constructor if one is not specified. An empty constructor function or one that just delegates to a parent class is unnecessary. eslint: [`no-useless-constructor`](https://eslint.org/docs/rules/no-useless-constructor)
+
+
+ - [9.5](#constructors--no-useless) 如果没有特别定义,类有默认的构造方法。一个空的构造函数或只是代表父类的构造函数是不需要写的。 eslint: [`no-useless-constructor`](http://eslint.org/docs/rules/no-useless-constructor)
```javascript
// bad
@@ -1214,6 +1335,7 @@ Other Style Guides
// bad
class Rey extends Jedi {
+ // 这种构造函数是不需要写的
constructor(...args) {
super(...args);
}
@@ -1228,10 +1350,11 @@ Other Style Guides
}
```
+
- - [9.6](#classes--no-duplicate-members) Avoid duplicate class members. eslint: [`no-dupe-class-members`](https://eslint.org/docs/rules/no-dupe-class-members)
+ - [9.6](#classes--no-duplicate-members) 避免重复定义类成员。eslint: [`no-dupe-class-members`](http://eslint.org/docs/rules/no-dupe-class-members)
- > Why? Duplicate class member declarations will silently prefer the last one - having duplicates is almost certainly a bug.
+ > 为什么?重复定义类成员只会使用最后一个被定义的 —— 重复本身也是一个 bug.
```javascript
// bad
@@ -1251,14 +1374,50 @@ Other Style Guides
}
```
-**[⬆ back to top](#table-of-contents)**
+
+ - [9.7](#classes--methods-use-this) 除非外部库或框架需要使用特定的非静态方法,否则类方法应该使用 `this` 或被写成静态方法。
+ 作为一个实例方法表明它应该根据实例的属性有不同的行为。eslint: [`class-methods-use-this`](https://eslint.org/docs/rules/class-methods-use-this)
-## Modules
+ ```javascript
+ // bad
+ class Foo {
+ bar() {
+ console.log('bar');
+ }
+ }
-
- - [10.1](#modules--use-them) Always use modules (`import`/`export`) over a non-standard module system. You can always transpile to your preferred module system.
+ // good - this 被使用了
+ class Foo {
+ bar() {
+ console.log(this.bar);
+ }
+ }
- > Why? Modules are the future, let’s start using the future now.
+ // good - constructor 不一定要使用 this
+ class Foo {
+ constructor() {
+ // ...
+ }
+ }
+
+ // good - 静态方法不需要使用 this
+ class Foo {
+ static bar() {
+ console.log('bar');
+ }
+ }
+ ```
+
+**[⬆ 返回顶部](#目录)**
+
+## 模块
+
+
+
+
+ - [10.1](#modules--use-them) 使用(`import`/`export`)模块而不是非标准的模块系统。你可以随时转到你喜欢的模块系统。
+
+ > 为什么?模块化是未来,让我们现在就开启未来吧。
```javascript
// bad
@@ -1274,10 +1433,11 @@ Other Style Guides
export default es6;
```
-
- - [10.2](#modules--no-wildcard) Do not use wildcard imports.
+
+
+ - [10.2](#modules--no-wildcard) 不要用 `import` 通配符, 即 `*` 这种方式。
- > Why? This makes sure you have a single default export.
+ > 为什么?这确保你有单个默认的导出。
```javascript
// bad
@@ -1287,10 +1447,12 @@ Other Style Guides
import AirbnbStyleGuide from './AirbnbStyleGuide';
```
-
- - [10.3](#modules--no-export-from-import) And do not export directly from an import.
+
+
- > Why? Although the one-liner is concise, having one clear way to import and one clear way to export makes things consistent.
+ - [10.3](#modules--no-export-from-import) 不要直接从 `import` 中直接 `export`。
+
+ > 为什么?虽然只写一行很简洁,但是使用明确 `import` 和明确的 `export` 来保证一致性。
```javascript
// bad
@@ -1303,15 +1465,17 @@ Other Style Guides
export default es6;
```
+
- - [10.4](#modules--no-duplicate-imports) Only import from a path in one place.
- eslint: [`no-duplicate-imports`](https://eslint.org/docs/rules/no-duplicate-imports)
- > Why? Having multiple lines that import from the same path can make code harder to maintain.
+
+ - [10.4](#modules--no-duplicate-imports) 一个路径只 `import` 一次。eslint: [`no-duplicate-imports`](http://eslint.org/docs/rules/no-duplicate-imports)
+
+ > 为什么?多行导入同一路径将使代码变得难以维护。
```javascript
// bad
import foo from 'foo';
- // … some other imports … //
+ // … 其他导入 … //
import { named1, named2 } from 'foo';
// good
@@ -1324,25 +1488,29 @@ Other Style Guides
} from 'foo';
```
+
- - [10.5](#modules--no-mutable-exports) Do not export mutable bindings.
- eslint: [`import/no-mutable-exports`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md)
- > Why? Mutation should be avoided in general, but in particular when exporting mutable bindings. While this technique may be needed for some special cases, in general, only constant references should be exported.
+
+ - [10.5](#modules--no-mutable-exports) 不要导出可变的东西。eslint: [`import/no-mutable-exports`](https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md)
+
+ > 为什么?变化通常都是需要避免,特别是当你要输出可变的绑定。虽然在某些场景下可能需要这种技术,但总的来说应该导出常量。
```javascript
// bad
let foo = 3;
- export { foo };
+ export { foo }
// good
const foo = 3;
- export { foo };
+ export { foo }
```
+
- - [10.6](#modules--prefer-default-export) In modules with a single export, prefer default export over named export.
- eslint: [`import/prefer-default-export`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md)
- > Why? To encourage more files that only ever export one thing, which is better for readability and maintainability.
+
+ - [10.6](#modules--prefer-default-export) 在一个单一导出模块里,用 `export default` 更好。eslint: [`import/prefer-default-export`](https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md)
+
+ > 为什么?鼓励使用更多文件,每个文件只导出一次,这样可读性和可维护性更好。
```javascript
// bad
@@ -1352,10 +1520,12 @@ Other Style Guides
export default function foo() {}
```
+
- - [10.7](#modules--imports-first) Put all `import`s above non-import statements.
- eslint: [`import/first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md)
- > Why? Since `import`s are hoisted, keeping them all at the top prevents surprising behavior.
+
+ - [10.7](#modules--imports-first) 把 `import` 放在其他所有语句之前。eslint: [`import/first`](https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/first.md)
+
+ > 为什么?因为 `import` 会被提升到代码最前面运行,因此将他们放在最前面以防止发生意外行为。
```javascript
// bad
@@ -1371,10 +1541,11 @@ Other Style Guides
foo.init();
```
+
- - [10.8](#modules--multiline-imports-over-newlines) Multiline imports should be indented just like multiline array and object literals.
+ - [10.8](#modules--multiline-imports-over-newlines) 多行 `import` 应该缩进,就像多行数组和对象字面量一样。eslint: [`object-curly-newline`](https://eslint.org/docs/rules/object-curly-newline)
- > Why? The curly braces follow the same indentation rules as every other curly brace block in the style guide, as do the trailing commas.
+ > 为什么?花括号与样式指南中每个其他花括号块遵循相同的缩进规则,逗号也是。
```javascript
// bad
@@ -1390,10 +1561,11 @@ Other Style Guides
} from 'path';
```
+
- - [10.9](#modules--no-webpack-loader-syntax) Disallow Webpack loader syntax in module import statements.
- eslint: [`import/no-webpack-loader-syntax`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md)
- > Why? Since using Webpack syntax in the imports couples the code to a module bundler. Prefer using the loader syntax in `webpack.config.js`.
+ - [10.9](#modules--no-webpack-loader-syntax) 在 `import` 语句里不允许 Webpack loader 语法。eslint: [`import/no-webpack-loader-syntax`](https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md)
+
+ > 为什么?一旦用 Webpack 语法在 import 里会把代码耦合到模块绑定器。最好是在 `webpack.config.js` 里写 webpack loader 语法
```javascript
// bad
@@ -1405,16 +1577,35 @@ Other Style Guides
import barCss from 'bar.css';
```
-**[⬆ back to top](#table-of-contents)**
+
+
+ - [10.10](#modules--import-extensions) import JavaScript文件不用包含扩展名
+ eslint: [`import/extensions`](https://github.com/import-js/eslint-plugin-import/blob/master/docs/rules/extensions.md)
+ > 为什么? 使用扩展名重构不友好,而且让模块使用者去了解模块的实现细节是不合适的。
+
+ ```javascript
+ // bad
+ import foo from './foo.js';
+ import bar from './bar.jsx';
+ import baz from './baz/index.jsx';
+
+ // good
+ import foo from './foo';
+ import bar from './bar';
+ import baz from './baz';
+ ```
+
+**[⬆ 返回顶部](#目录)**
-## Iterators and Generators
+## 迭代器与生成器
-
- - [11.1](#iterators--nope) Don’t use iterators. Prefer JavaScript’s higher-order functions instead of loops like `for-in` or `for-of`. eslint: [`no-iterator`](https://eslint.org/docs/rules/no-iterator.html) [`no-restricted-syntax`](https://eslint.org/docs/rules/no-restricted-syntax)
+
+
+ - [11.1](#iterators--nope) 不要用迭代器。使用 JavaScript 高级函数代替 `for-in`、 `for-of`。eslint: [`no-iterator`](http://eslint.org/docs/rules/no-iterator) [`no-restricted-syntax`](http://eslint.org/docs/rules/no-restricted-syntax)
- > Why? This enforces our immutable rule. Dealing with pure functions that return values is easier to reason about than side effects.
+ > 为什么?这强调了我们不可变的规则。 处理返回值的纯函数比处理副作用更容易。
- > Use `map()` / `every()` / `filter()` / `find()` / `findIndex()` / `reduce()` / `some()` / ... to iterate over arrays, and `Object.keys()` / `Object.values()` / `Object.entries()` to produce arrays so you can iterate over objects.
+ > 用数组的这些迭代方法: `map()` / `every()` / `filter()` / `find()` / `findIndex()` / `reduce()` / `some()` / ... , 用对象的这些方法 `Object.keys()` / `Object.values()` / `Object.entries()` 去产生一个数组,这样你就能去遍历对象了。
```javascript
const numbers = [1, 2, 3, 4, 5];
@@ -1428,9 +1619,7 @@ Other Style Guides
// good
let sum = 0;
- numbers.forEach((num) => {
- sum += num;
- });
+ numbers.forEach((num) => sum += num);
sum === 15;
// best (use the functional force)
@@ -1443,27 +1632,30 @@ Other Style Guides
increasedByOne.push(numbers[i] + 1);
}
- // good
+ // good
const increasedByOne = [];
numbers.forEach((num) => {
increasedByOne.push(num + 1);
});
// best (keeping it functional)
- const increasedByOne = numbers.map(num => num + 1);
+ const increasedByOne = numbers.map((num) => num + 1);
```
-
- - [11.2](#generators--nope) Don’t use generators for now.
+
+
+ - [11.2](#generators--nope) 现在暂时不要使用生成器。
- > Why? They don’t transpile well to ES5.
+ > 为什么?生成器目前不能很好地转换为 ES5 语法。
+
- - [11.3](#generators--spacing) If you must use generators, or if you disregard [our advice](#generators--nope), make sure their function signature is spaced properly. eslint: [`generator-star-spacing`](https://eslint.org/docs/rules/generator-star-spacing)
- > Why? `function` and `*` are part of the same conceptual keyword - `*` is not a modifier for `function`, `function*` is a unique construct, different from `function`.
+ - [11.3](#generators--spacing) 如果你一定要用生成器,或者你忽略 [我们的建议](#generators--nope),请确保它们的函数标志空格是得当的。eslint: [`generator-star-spacing`](http://eslint.org/docs/rules/generator-star-spacing)
- ```javascript
+ > 为什么?`function` 和 `*` 是同一概念关键字 - `*`不是`function`的修饰符,`function*` 是一个和`function` 不一样的独特结构。
+
+ ```js
// bad
function * foo() {
// ...
@@ -1472,17 +1664,17 @@ Other Style Guides
// bad
const bar = function * () {
// ...
- };
+ }
// bad
const baz = function *() {
// ...
- };
+ }
// bad
const quux = function*() {
// ...
- };
+ }
// bad
function*foo() {
@@ -1506,7 +1698,7 @@ Other Style Guides
*
() {
// ...
- };
+ }
// good
function* foo() {
@@ -1516,15 +1708,18 @@ Other Style Guides
// good
const foo = function* () {
// ...
- };
+ }
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Properties
-
- - [12.1](#properties--dot) Use dot notation when accessing properties. eslint: [`dot-notation`](https://eslint.org/docs/rules/dot-notation.html)
+## 属性
+
+
+
+
+ - [12.1](#properties--dot) 访问属性时使用点符号。eslint: [`dot-notation`](http://eslint.org/docs/rules/dot-notation)
```javascript
const luke = {
@@ -1539,8 +1734,10 @@ Other Style Guides
const isJedi = luke.jedi;
```
-
- - [12.2](#properties--bracket) Use bracket notation `[]` when accessing properties with a variable.
+
+
+
+ - [12.2](#properties--bracket) 当使用变量获取属性时用方括号 `[]`。
```javascript
const luke = {
@@ -1554,8 +1751,10 @@ Other Style Guides
const isJedi = getProp('jedi');
```
+
+
- - [12.3](#es2016-properties--exponentiation-operator) Use exponentiation operator `**` when calculating exponentiations. eslint: [`no-restricted-properties`](https://eslint.org/docs/rules/no-restricted-properties).
+ - [12.3](#es2016-properties--exponentiation-operator) 做幂运算时用幂操作符 `**` 。eslint: [`prefer-exponentiation-operator`](https://eslint.org/docs/rules/prefer-exponentiation-operator)。
```javascript
// bad
@@ -1565,12 +1764,15 @@ Other Style Guides
const binary = 2 ** 10;
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Variables
-
- - [13.1](#variables--const) Always use `const` or `let` to declare variables. Not doing so will result in global variables. We want to avoid polluting the global namespace. Captain Planet warned us of that. eslint: [`no-undef`](https://eslint.org/docs/rules/no-undef) [`prefer-const`](https://eslint.org/docs/rules/prefer-const)
+## 变量
+
+
+
+
+ - [13.1](#variables--const) 使用 `const` 或 `let` 声明变量。不这样做会导致全局变量。我们想要避免污染全局命名空间。地球超人也这样警告我们(译者注:可能是一个冷笑话)。 eslint: [`no-undef`](http://eslint.org/docs/rules/no-undef) [`prefer-const`](http://eslint.org/docs/rules/prefer-const)
```javascript
// bad
@@ -1580,10 +1782,12 @@ Other Style Guides
const superPower = new SuperPower();
```
-
- - [13.2](#variables--one-const) Use one `const` or `let` declaration per variable. eslint: [`one-var`](https://eslint.org/docs/rules/one-var.html)
+
+
- > Why? It’s easier to add new variable declarations this way, and you never have to worry about swapping out a `;` for a `,` or introducing punctuation-only diffs. You can also step through each declaration with the debugger, instead of jumping through all of them at once.
+ - [13.2](#variables--one-const) 为每个变量声明都用一个 `const` 或 `let `。eslint: [`one-var`](http://eslint.org/docs/rules/one-var)
+
+ > 为什么?这种方式很容易去声明新的变量,你不用去考虑把 `;` 调换成 `,`,或者引入一个只有标点的不同的变化(译者注:这里说的应该是在 Git 提交代码时显示的变化)。这种做法也可以是你在调试的时候单步每个声明语句,而不是一下跳过所有声明。
```javascript
// bad
@@ -1592,7 +1796,7 @@ Other Style Guides
dragonball = 'z';
// bad
- // (compare to above, and try to spot the mistake)
+ // (与前面的比较,找一找错误)
const items = getItems(),
goSportsTeam = true;
dragonball = 'z';
@@ -1603,10 +1807,12 @@ Other Style Guides
const dragonball = 'z';
```
-
- - [13.3](#variables--const-let-group) Group all your `const`s and then group all your `let`s.
+
+
+
+ - [13.3](#variables--const-let-group) 把`const` 和 `let` 分别放一起。
- > Why? This is helpful when later on you might need to assign a variable depending on one of the previous assigned variables.
+ > 为什么?在你需要分配一个新的变量,而这个变量依赖之前分配过的变量的时候,这种做法是有帮助的。
```javascript
// bad
@@ -1629,13 +1835,14 @@ Other Style Guides
let length;
```
-
- - [13.4](#variables--define-where-used) Assign variables where you need them, but place them in a reasonable place.
+
+
+ - [13.4](#variables--define-where-used) 在你需要的地方声明变量,但是要放在合理的位置。
- > Why? `let` and `const` are block scoped and not function scoped.
+ > 为什么?`let` 和 `const` 都是块级作用域而不是函数级作用域。
```javascript
- // bad - unnecessary function call
+ // bad - 不必要的函数调用。
function checkName(hasName) {
const name = getName();
@@ -1657,6 +1864,7 @@ Other Style Guides
return false;
}
+ // 在需要的时候分配
const name = getName();
if (name === 'test') {
@@ -1667,22 +1875,22 @@ Other Style Guides
return name;
}
```
-
- - [13.5](#variables--no-chain-assignment) Don’t chain variable assignments. eslint: [`no-multi-assign`](https://eslint.org/docs/rules/no-multi-assign)
+
+
+ - [13.5](#variables--no-chain-assignment) 不要使用链式声明变量。 eslint: [`no-multi-assign`](https://eslint.org/docs/rules/no-multi-assign)
- > Why? Chaining variable assignments creates implicit global variables.
+ > 为什么?链式声明变量会创建隐式全局变量。
```javascript
// bad
(function example() {
- // JavaScript interprets this as
+ // JavaScript 将这一段解释为
// let a = ( b = ( c = 1 ) );
- // The let keyword only applies to variable a; variables b and c become
- // global variables.
+ // let 只对变量 a 起作用; 变量 b 和 c 都变成了全局变量
let a = b = c = 1;
}());
- console.log(a); // throws ReferenceError
+ console.log(a); // undefined
console.log(b); // 1
console.log(c); // 1
@@ -1693,51 +1901,55 @@ Other Style Guides
let c = a;
}());
- console.log(a); // throws ReferenceError
- console.log(b); // throws ReferenceError
- console.log(c); // throws ReferenceError
+ console.log(a); // undefined
+ console.log(b); // undefined
+ console.log(c); // undefined
- // the same applies for `const`
+ // `const` 也是如此
```
-
- - [13.6](#variables--unary-increment-decrement) Avoid using unary increments and decrements (`++`, `--`). eslint [`no-plusplus`](https://eslint.org/docs/rules/no-plusplus)
+
+
- > Why? Per the eslint documentation, unary increment and decrement statements are subject to automatic semicolon insertion and can cause silent errors with incrementing or decrementing values within an application. It is also more expressive to mutate your values with statements like `num += 1` instead of `num++` or `num ++`. Disallowing unary increment and decrement statements also prevents you from pre-incrementing/pre-decrementing values unintentionally which can also cause unexpected behavior in your programs.
+ - [13.6](#variables--unary-increment-decrement) 不要使用一元自增自减运算符(`++`, `--`). eslint [`no-plusplus`](http://eslint.org/docs/rules/no-plusplus)
+
+ > 为什么?根据 eslint 文档,一元增量和减量语句受到自动分号插入的影响,并且可能会导致应用程序中的值递增或递减的静默错误。 使用 `num + = 1` 而不是 `num ++` 或 `num ++` 语句也是含义清晰的。 禁止一元增量和减量语句还会阻止您无意地预增/预减值,这也会导致程序出现意外行为。
```javascript
- // bad
+ // bad
- const array = [1, 2, 3];
- let num = 1;
- num++;
- --num;
+ const array = [1, 2, 3];
+ let num = 1;
+ num++;
+ --num;
- let sum = 0;
- let truthyCount = 0;
- for (let i = 0; i < array.length; i++) {
- let value = array[i];
- sum += value;
- if (value) {
- truthyCount++;
+ let sum = 0;
+ let truthyCount = 0;
+ for (let i = 0; i < array.length; i++) {
+ let value = array[i];
+ sum += value;
+ if (value) {
+ truthyCount++;
+ }
}
- }
- // good
+ // good
- const array = [1, 2, 3];
- let num = 1;
- num += 1;
- num -= 1;
+ const array = [1, 2, 3];
+ let num = 1;
+ num += 1;
+ num -= 1;
- const sum = array.reduce((a, b) => a + b, 0);
- const truthyCount = array.filter(Boolean).length;
+ const sum = array.reduce((a, b) => a + b, 0);
+ const truthyCount = array.filter(Boolean).length;
```
-
- - [13.7](#variables--linebreak) Avoid linebreaks before or after `=` in an assignment. If your assignment violates [`max-len`](https://eslint.org/docs/rules/max-len.html), surround the value in parens. eslint [`operator-linebreak`](https://eslint.org/docs/rules/operator-linebreak.html).
+
+
+
+ - [13.7](#variables--linebreak) 在赋值的时候避免在 `=` 前/后换行。 如果你的赋值语句超出 [`max-len`](https://eslint.org/docs/rules/max-len),那就用小括号把这个值包起来再换行。eslint [`operator-linebreak`](https://eslint.org/docs/rules/operator-linebreak).
- > Why? Linebreaks surrounding `=` can obfuscate the value of an assignment.
+ > 为什么?在 `=` 附近换行容易混淆这个赋值语句。
```javascript
// bad
@@ -1757,79 +1969,78 @@ Other Style Guides
const foo = 'superLongLongLongLongLongLongLongLongString';
```
-
- - [13.8](#variables--no-unused-vars) Disallow unused variables. eslint: [`no-unused-vars`](https://eslint.org/docs/rules/no-unused-vars)
+
+
- > Why? Variables that are declared and not used anywhere in the code are most likely an error due to incomplete refactoring. Such variables take up space in the code and can lead to confusion by readers.
+ - [13.8](#variables--no-unused-vars) 不允许有未使用的变量。eslint: [`no-unused-vars`](https://eslint.org/docs/rules/no-unused-vars)
+
+ > 为什么?一个声明了但未使用的变量更像是由于重构未完成产生的错误。这种在代码中出现的变量会使阅读者迷惑。
```javascript
// bad
- var some_unused_var = 42;
+ const some_unused_var = 42;
- // Write-only variables are not considered as used.
- var y = 10;
+ // 写了没用
+ let y = 10;
y = 5;
- // A read for a modification of itself is not considered as used.
- var z = 0;
+ // 变量改了自己的值,也没有用这个变量
+ let z = 0;
z = z + 1;
- // Unused function arguments.
+ // 参数定义了但未使用
function getX(x, y) {
return x;
}
// good
-
function getXPlusY(x, y) {
return x + y;
}
- var x = 1;
- var y = a + 2;
+ const x = 1;
+ const y = a + 2;
alert(getXPlusY(x, y));
- // 'type' is ignored even if unused because it has a rest property sibling.
- // This is a form of extracting an object that omits the specified keys.
- var { type, ...coords } = data;
- // 'coords' is now the 'data' object without its 'type' property.
+ // 'type' 即使没有使用也可以可以被忽略, 因为这个有一个 rest 取值的属性。
+ // 这是从对象中抽取一个忽略特殊字段的对象的一种形式
+ const { type, ...coords } = data;
+ // 'coords' 现在就是一个没有 'type' 属性的 'data' 对象
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Hoisting
+## 提升
-
- - [14.1](#hoisting--about) `var` declarations get hoisted to the top of their closest enclosing function scope, their assignment does not. `const` and `let` declarations are blessed with a new concept called [Temporal Dead Zones (TDZ)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#Temporal_Dead_Zone). It’s important to know why [typeof is no longer safe](http://es-discourse.com/t/why-typeof-is-no-longer-safe/15).
+
+
+
+ - [14.1](#hoisting--about) `var` 声明会被提前到离他最近的作用域的最前面,但是它的赋值语句并没有提前。`const` 和 `let` 被赋予了新的概念 [暂时性死区 (TDZ)](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let#temporal_dead_zone_tdz)。 重要的是要知道为什么 [typeof 不再安全](https://web.archive.org/web/20200121061528/http://es-discourse.com/t/why-typeof-is-no-longer-safe/15)。
```javascript
- // we know this wouldn’t work (assuming there
- // is no notDefined global variable)
+ // 我们知道这个不会工作,假设没有定义全局的 notDefined
function example() {
console.log(notDefined); // => throws a ReferenceError
}
- // creating a variable declaration after you
- // reference the variable will work due to
- // variable hoisting. Note: the assignment
- // value of `true` is not hoisted.
+ // 在你引用的地方之后声明一个变量,他会正常输出是因为变量提升。
+ // 注意: declaredButNotAssigned 的值 true 没有被提升。
function example() {
console.log(declaredButNotAssigned); // => undefined
var declaredButNotAssigned = true;
}
- // the interpreter is hoisting the variable
- // declaration to the top of the scope,
- // which means our example could be rewritten as:
+ // 解释器把变量声明提升到作用域最前面,
+ // 可以重写成如下例子, 二者意义相同。
function example() {
let declaredButNotAssigned;
console.log(declaredButNotAssigned); // => undefined
declaredButNotAssigned = true;
}
- // using const and let
+ // 用 const,let就不一样了。
function example() {
console.log(declaredButNotAssigned); // => throws a ReferenceError
console.log(typeof declaredButNotAssigned); // => throws a ReferenceError
@@ -1837,8 +2048,10 @@ Other Style Guides
}
```
-
- - [14.2](#hoisting--anon-expressions) Anonymous function expressions hoist their variable name, but not the function assignment.
+
+
+
+ - [14.2](#hoisting--anon-expressions) 匿名函数表达式和 `var` 情况相同。
```javascript
function example() {
@@ -1846,14 +2059,16 @@ Other Style Guides
anonymous(); // => TypeError anonymous is not a function
+ // 译者注,不管后面是函数、数字还是字符串,都是一样的,总结就是实际代码中最好不要用 var。
var anonymous = function () {
console.log('anonymous function expression');
};
}
```
-
- - [14.3](#hoisting--named-expressions) Named function expressions hoist the variable name, not the function name or the function body.
+
+
+ - [14.3](#hoisting--named-expresions) 已命名函数表达式提升他的变量名,不是函数名或函数体。
```javascript
function example() {
@@ -1868,8 +2083,7 @@ Other Style Guides
};
}
- // the same is true when the function name
- // is the same as the variable name.
+ // 函数名和变量名一样是也如此。
function example() {
console.log(named); // => undefined
@@ -1881,8 +2095,9 @@ Other Style Guides
}
```
-
- - [14.4](#hoisting--declarations) Function declarations hoist their name and the function body.
+
+
+ - [14.4](#hoisting--declarations) 函数声明则提升了函数名和函数体。
```javascript
function example() {
@@ -1893,35 +2108,91 @@ Other Style Guides
}
}
```
+
+
+ - [14.5](#no-use-before-define) 变量、类、函数都应该在使用前定义。 eslint: [`no-use-before-define`](https://eslint.org/docs/latest/rules/no-use-before-define)
+
+ > 为什么? 当变量、类或者函数在使用处之后定义,这让阅读者很难想到这个函数引用自何处。 对于读者在遇到某个事物之前,如果能知道这个事物的来源(不论是在文件中定义还是从别的模块引用),理解起来都会清晰很多。
+
+ ```javascript
+ // 不好的
+
+ // 变量 a 使用出现在定义之前
+ console.log(a); // 这样会导致 undefined,虽然变量声明被提升了, 但 a 初始化复制却还没执行
+ var a = 10;
+
+ // 函数 fun 使用出现在定义之前
+ fun();
+ function fun() {}
+
+ // 类 A 使用出现在定义之前
+ new A(); // 引用错误: 无法在 A 初始化之前访问它
+ class A {
+ }
- - For more information refer to [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/) by [Ben Cherry](http://www.adequatelygood.com/).
+ // `let` 和 `const` 被提升, 但是他们没有初始化变量值
+ // 变量 a、 b 都被放在了 JavaScript 的暂时性死区 (Temporal Dead Zone, 指在变量被声明之前无法访问它的现象)。
-**[⬆ back to top](#table-of-contents)**
+ console.log(a); // 引用错误: 无法在 a 初始化之前访问它
+ console.log(b); // 引用错误: 无法在 b 初始化之前访问它
+ let a = 10;
+ const b = 5;
-## Comparison Operators & Equality
-
- - [15.1](#comparison--eqeqeq) Use `===` and `!==` over `==` and `!=`. eslint: [`eqeqeq`](https://eslint.org/docs/rules/eqeqeq.html)
+ // 好的
-
- - [15.2](#comparison--if) Conditional statements such as the `if` statement evaluate their expression using coercion with the `ToBoolean` abstract method and always follow these simple rules:
+ var a = 10;
+ console.log(a); // 10
- - **Objects** evaluate to **true**
- - **Undefined** evaluates to **false**
- - **Null** evaluates to **false**
- - **Booleans** evaluate to **the value of the boolean**
- - **Numbers** evaluate to **false** if **+0, -0, or NaN**, otherwise **true**
- - **Strings** evaluate to **false** if an empty string `''`, otherwise **true**
+ function fun() {}
+ fun();
+
+ class A {
+ }
+ new A();
+
+ let a = 10;
+ const b = 5;
+ console.log(a); // 10
+ console.log(b); // 5
+ ```
+ - 详情请见 [JavaScript Scoping & Hoisting](http://www.adequatelygood.com/2010/2/JavaScript-Scoping-and-Hoisting/) by [Ben Cherry](http://www.adequatelygood.com/).
+
+**[⬆ 返回顶部](#目录)**
+
+
+## 比较运算符与相等
+
+
+
+ - [15.1](#comparison--eqeqeq) 用 `===` 和 `!==` 而不是 `==` 和 `!=`. eslint: [`eqeqeq`](http://eslint.org/docs/rules/eqeqeq)
+
+
+
+
+ - [15.2](#comparison--if) 条件语句如 `if` 语句使用强制 `ToBoolean` 抽象方法来计算它们的表达式,并且始终遵循以下简单规则:
+
+ + **Objects** 计算成 **true**
+ + **Undefined** 计算成 **false**
+ + **Null** 计算成 **false**
+ + **Booleans** 计算成 **the value of the boolean**
+ + **Numbers**
+ + **+0, -0, or NaN** 计算成 **false**
+ + 其他 **true**
+ + **Strings**
+ + `''` 计算成 **false**
+ + 其他 **true**
```javascript
if ([0] && []) {
// true
- // an array (even an empty one) is an object, objects will evaluate to true
+ // 数组(即使是空数组)是对象,对象会计算成 true
}
```
-
- - [15.3](#comparison--shortcuts) Use shortcuts for booleans, but explicit comparisons for strings and numbers.
+
+
+ - [15.3](#comparison--shortcuts) 布尔值要用缩写,而字符串和数字要明确使用比较操作符。
```javascript
// bad
@@ -1955,13 +2226,17 @@ Other Style Guides
}
```
-
- - [15.4](#comparison--moreinfo) For more information see [Truth Equality and JavaScript](https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) by Angus Croll.
+
+
+
+ - [15.4](#comparison--moreinfo) 更多信息请见 Angus Croll 的 [Truth, Equality, and JavaScript](https://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108)。
+
+
+
-
- - [15.5](#comparison--switch-blocks) Use braces to create blocks in `case` and `default` clauses that contain lexical declarations (e.g. `let`, `const`, `function`, and `class`). eslint: [`no-case-declarations`](https://eslint.org/docs/rules/no-case-declarations.html)
+ - [15.5](#comparison--switch-blocks) 在 `case` 和 `default` 分句里用大括号创建一块包含词法声明的区域(例如:`let`、`const`、`function` 和 `class`)。eslint rules: [`no-case-declarations`](http://eslint.org/docs/rules/no-case-declarations).
- > Why? Lexical declarations are visible in the entire `switch` block but only get initialized when assigned, which only happens when its `case` is reached. This causes problems when multiple `case` clauses attempt to define the same thing.
+ > 为什么?词法声明在整个 `switch` 的代码块里都可见,但是只有当其被分配后才会初始化,仅当这个 `case` 被执行时才被初始化。当多个 `case` 分句试图定义同一个对象时就会出现问题。
```javascript
// bad
@@ -2006,8 +2281,10 @@ Other Style Guides
}
```
-
- - [15.6](#comparison--nested-ternaries) Ternaries should not be nested and generally be single line expressions. eslint: [`no-nested-ternary`](https://eslint.org/docs/rules/no-nested-ternary.html)
+
+
+
+ - [15.6](#comparison--nested-ternaries) 三元表达式不应该嵌套,通常是单行表达式。eslint rules: [`no-nested-ternary`](http://eslint.org/docs/rules/no-nested-ternary)
```javascript
// bad
@@ -2015,37 +2292,42 @@ Other Style Guides
? "bar"
: value1 > value2 ? "baz" : null;
- // split into 2 separated ternary expressions
+ // better
const maybeNull = value1 > value2 ? 'baz' : null;
- // better
const foo = maybe1 > maybe2
- ? 'bar'
+ ? 'bar'
: maybeNull;
// best
+ const maybeNull = value1 > value2 ? 'baz' : null;
+
const foo = maybe1 > maybe2 ? 'bar' : maybeNull;
```
-
- - [15.7](#comparison--unneeded-ternary) Avoid unneeded ternary statements. eslint: [`no-unneeded-ternary`](https://eslint.org/docs/rules/no-unneeded-ternary.html)
+
+
+ - [15.7](#comparison--unneeded-ternary) 避免不必要的三元表达式。eslint rules: [`no-unneeded-ternary`](http://eslint.org/docs/rules/no-unneeded-ternary)
```javascript
// bad
const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;
+ const quux = a != null ? a : b;
// good
const foo = a || b;
const bar = !!c;
const baz = !c;
+ const quux = a ?? b;
```
+
- - [15.8](#comparison--no-mixed-operators) When mixing operators, enclose them in parentheses. The only exception is the standard arithmetic operators (`+`, `-`, `*`, & `/`) since their precedence is broadly understood. eslint: [`no-mixed-operators`](https://eslint.org/docs/rules/no-mixed-operators.html)
+ - [15.8](#comparison--no-mixed-operators) 用圆括号来组合多种操作符。唯一里的例外就是像 `+`, `-`, 和 `**` 这种优先级容易理解的运算符。我们还是建议把 `/` `*` 放到小括号里, 因为他们混用的时候优先级容易有歧义。 eslint: [`no-mixed-operators`](https://eslint.org/docs/rules/no-mixed-operators)
- > Why? This improves readability and clarifies the developer’s intention.
+ > 为什么?这提高了可读性,并且明确了开发者的意图。
```javascript
// bad
@@ -2055,11 +2337,14 @@ Other Style Guides
const bar = a ** b - 5 % d;
// bad
- // one may be confused into thinking (a || b) && c
+ // 别人会陷入(a || b) && c 的迷惑中
if (a || b && c) {
return d;
}
+ // bad
+ const bar = a + b / c * d;
+
// good
const foo = (a && b < 0) || c > 0 || (d + 1 === 0);
@@ -2072,15 +2357,44 @@ Other Style Guides
}
// good
- const bar = a + b / c * d;
+ const bar = a + (b / c) * d;
+ ```
+
+ - [15.9](#nullish-coalescing-operator) (`??`) 是一个逻辑运算符, 当运算符左侧是 null 或 undefined 时返回右侧的值, 否则返回左侧值。
+
+ > 为什么? (`??`)这个运算符通过精确区分null/undefined和其他"falsy"值,从而增强了代码的清晰度和可预测性。
+
+ ```javascript
+ // 不好的
+ const value = 0 ?? 'default';
+ // returns 0, not 'default'
+
+ // 不好的
+ const value = '' ?? 'default';
+ // returns '', not 'default'
+
+ // 好的
+ const value = null ?? 'default';
+ // returns 'default'
+
+ // 好的
+ const user = {
+ name: 'John',
+ age: null
+ };
+ const age = user.age ?? 18;
+ // returns 18
```
-**[⬆ back to top](#table-of-contents)**
-## Blocks
+**[⬆ back to top](#目录)**
+
-
- - [16.1](#blocks--braces) Use braces with all multi-line blocks. eslint: [`nonblock-statement-body-position`](https://eslint.org/docs/rules/nonblock-statement-body-position)
+## 块
+
+
+
+ - [16.1](#blocks--braces) 用大括号包裹多行代码块。 eslint: [`nonblock-statement-body-position`](https://eslint.org/docs/rules/nonblock-statement-body-position)
```javascript
// bad
@@ -2104,8 +2418,9 @@ Other Style Guides
}
```
-
- - [16.2](#blocks--cuddled-elses) If you’re using multi-line blocks with `if` and `else`, put `else` on the same line as your `if` block’s closing brace. eslint: [`brace-style`](https://eslint.org/docs/rules/brace-style.html)
+
+
+ - [16.2](#blocks--cuddled-elses) `if` 表达式的 `else`和 `if` 的右大括号在一行。eslint: [`brace-style`](http://eslint.org/docs/rules/brace-style)
```javascript
// bad
@@ -2126,8 +2441,10 @@ Other Style Guides
}
```
-
- - [16.3](#blocks--no-else-return) If an `if` block always executes a `return` statement, the subsequent `else` block is unnecessary. A `return` in an `else if` block following an `if` block that contains a `return` can be separated into multiple `if` blocks. eslint: [`no-else-return`](https://eslint.org/docs/rules/no-else-return)
+
+
+
+ - [16.3](#blocks--no-else-return) 如果 `if` 语句中总是需要用 `return` 返回,那后续的 `else` 就不需要写了。 `if` 块中包含 `return`, 它后面的 `else if` 块中也包含了 `return`, 这个时候就可以把 `return` 分到多个 `if` 语句块中。 eslint: [`no-else-return`](https://eslint.org/docs/rules/no-else-return)
```javascript
// bad
@@ -2191,14 +2508,15 @@ Other Style Guides
}
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Control Statements
+## 控制语句
+
- - [17.1](#control-statements) In case your control statement (`if`, `while` etc.) gets too long or exceeds the maximum line length, each (grouped) condition could be put into a new line. The logical operator should begin the line.
+ - [17.1](#control-statements) 当你的控制语句(`if`, `while` 等)太长或者超过最大长度限制的时候,把每一个(组)判断条件放在单独一行里。逻辑操作符放在行首。
- > Why? Requiring operators at the beginning of the line keeps the operators aligned and follows a pattern similar to method chaining. This also improves readability by making it easier to visually follow complex logic.
+ > 为什么?把逻辑操作符放在行首是让操作符的对齐方式和链式函数保持一致。这提高了可读性,也让复杂逻辑更清晰。
```javascript
// bad
@@ -2249,8 +2567,9 @@ Other Style Guides
}
```
-
- - [17.2](#control-statements--value-selection) Don't use selection operators in place of control statements.
+
+
+ - [17.2](#control-statements--value-selection) 不要用选择操作符代替控制语句。
```javascript
// bad
@@ -2262,12 +2581,13 @@ Other Style Guides
}
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Comments
+## 注释
-
- - [18.1](#comments--multiline) Use `/** ... */` for multi-line comments.
+
+
+ - [18.1](#comments--multiline) 多行注释用 `/** ... */`。
```javascript
// bad
@@ -2296,8 +2616,9 @@ Other Style Guides
}
```
-
- - [18.2](#comments--singleline) Use `//` for single line comments. Place single line comments on a newline above the subject of the comment. Put an empty line before the comment unless it’s on the first line of a block.
+
+
+ - [18.2](#comments--singleline) 单行注释用 `//`,将单行注释放在被注释区域上面。如果注释不是在第一行,那么注释前面就空一行。
```javascript
// bad
@@ -2311,7 +2632,7 @@ Other Style Guides
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
- const type = this.type || 'no type';
+ const type = this._type || 'no type';
return type;
}
@@ -2321,7 +2642,7 @@ Other Style Guides
console.log('fetching type...');
// set the default type to 'no type'
- const type = this.type || 'no type';
+ const type = this._type || 'no type';
return type;
}
@@ -2329,14 +2650,15 @@ Other Style Guides
// also good
function getType() {
// set the default type to 'no type'
- const type = this.type || 'no type';
+ const type = this._type || 'no type';
return type;
}
```
+
- - [18.3](#comments--spaces) Start all comments with a space to make it easier to read. eslint: [`spaced-comment`](https://eslint.org/docs/rules/spaced-comment)
+ - [18.3](#comments--spaces) 所有注释开头空一格,方便阅读。eslint: [`spaced-comment`](http://eslint.org/docs/rules/spaced-comment)
```javascript
// bad
@@ -2372,25 +2694,29 @@ Other Style Guides
}
```
-
- - [18.4](#comments--actionitems) Prefixing your comments with `FIXME` or `TODO` helps other developers quickly understand if you’re pointing out a problem that needs to be revisited, or if you’re suggesting a solution to the problem that needs to be implemented. These are different than regular comments because they are actionable. The actions are `FIXME: -- need to figure this out` or `TODO: -- need to implement`.
+
+
+ - [18.4](#comments--actionitems) 在你的注释前使用 `FIXME` 或 `TODO` 前缀,这有助于其他开发人员快速理解你指出的需要修复的问题, 或者您建议需要实现的问题的解决方案。 这些不同于常规注释,它们是有明确含义的。`FIXME:需要修复这个问题`或`TODO:需要实现的功能`。
-
- - [18.5](#comments--fixme) Use `// FIXME:` to annotate problems.
+
+
+
+ - [18.5](#comments--fixme) 用 `// FIXME:` 给问题做注释。
```javascript
class Calculator extends Abacus {
constructor() {
super();
- // FIXME: shouldn’t use a global here
+ // FIXME: shouldn't use a global here
total = 0;
}
}
```
-
- - [18.6](#comments--todo) Use `// TODO:` to annotate solutions to problems.
+
+
+ - [18.6](#comments--todo) 用 `// TODO:` 去注释问题的解决方案。
```javascript
class Calculator extends Abacus {
@@ -2403,32 +2729,36 @@ Other Style Guides
}
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
+
-## Whitespace
+## 空格
-
- - [19.1](#whitespace--spaces) Use soft tabs (space character) set to 2 spaces. eslint: [`indent`](https://eslint.org/docs/rules/indent.html)
+
+
+
+ - [19.1](#whitespace--spaces) 一个缩进使用两个空格。eslint: [`indent`](http://eslint.org/docs/rules/indent)
```javascript
// bad
function foo() {
- ∙∙∙∙let name;
+ ∙∙∙∙const name;
}
// bad
function bar() {
- ∙let name;
+ ∙const name;
}
// good
function baz() {
- ∙∙let name;
+ ∙∙const name;
}
```
-
- - [19.2](#whitespace--before-blocks) Place 1 space before the leading brace. eslint: [`space-before-blocks`](https://eslint.org/docs/rules/space-before-blocks.html)
+
+
+ - [19.2](#whitespace--before-blocks) 在大括号前空一格。eslint: [`space-before-blocks`](http://eslint.org/docs/rules/space-before-blocks)
```javascript
// bad
@@ -2454,8 +2784,9 @@ Other Style Guides
});
```
-
- - [19.3](#whitespace--around-keywords) Place 1 space before the opening parenthesis in control statements (`if`, `while` etc.). Place no space between the argument list and the function name in function calls and declarations. eslint: [`keyword-spacing`](https://eslint.org/docs/rules/keyword-spacing.html)
+
+
+ - [19.3](#whitespace--around-keywords) 在控制语句(`if`, `while` 等)的圆括号前空一格。在函数调用和定义时,参数列表和函数名之间不空格。 eslint: [`keyword-spacing`](http://eslint.org/docs/rules/keyword-spacing)
```javascript
// bad
@@ -2479,8 +2810,9 @@ Other Style Guides
}
```
-
- - [19.4](#whitespace--infix-ops) Set off operators with spaces. eslint: [`space-infix-ops`](https://eslint.org/docs/rules/space-infix-ops.html)
+
+
+ - [19.4](#whitespace--infix-ops) 用空格来隔开运算符。eslint: [`space-infix-ops`](http://eslint.org/docs/rules/space-infix-ops)
```javascript
// bad
@@ -2490,8 +2822,9 @@ Other Style Guides
const x = y + 5;
```
-
- - [19.5](#whitespace--newline-at-end) End files with a single newline character. eslint: [`eol-last`](https://github.com/eslint/eslint/blob/master/docs/rules/eol-last.md)
+
+
+ - [19.5](#whitespace--newline-at-end) 文件结尾空一行。eslint: [`eol-last`](https://eslint.org/docs/rules/eol-last)
```javascript
// bad
@@ -2504,8 +2837,8 @@ Other Style Guides
// bad
import { es6 } from './AirbnbStyleGuide';
// ...
- export default es6;↵
- ↵
+ export default es6;
+
```
```javascript
@@ -2515,9 +2848,10 @@ Other Style Guides
export default es6;↵
```
-
- - [19.6](#whitespace--chains) Use indentation when making long method chains (more than 2 method chains). Use a leading dot, which
- emphasizes that the line is a method call, not a new statement. eslint: [`newline-per-chained-call`](https://eslint.org/docs/rules/newline-per-chained-call) [`no-whitespace-before-property`](https://eslint.org/docs/rules/no-whitespace-before-property)
+
+
+
+ - [19.6](#whitespace--chains) 当出现长的方法链式调用时(>2个)用缩进。用点开头强调该行是一个方法调用,而不是一个新的语句。eslint: [`newline-per-chained-call`](http://eslint.org/docs/rules/newline-per-chained-call) [`no-whitespace-before-property`](http://eslint.org/docs/rules/no-whitespace-before-property)
```javascript
// bad
@@ -2542,7 +2876,7 @@ Other Style Guides
// bad
const leds = stage.selectAll('.led').data(data).enter().append('svg:svg').classed('led', true)
.attr('width', (radius + margin) * 2).append('svg:g')
- .attr('transform', `translate(${radius + margin},${radius + margin})`)
+ .attr('transform', `translate(${radius + margin}, ${radius + margin})`)
.call(tron.led);
// good
@@ -2552,15 +2886,20 @@ Other Style Guides
.classed('led', true)
.attr('width', (radius + margin) * 2)
.append('svg:g')
- .attr('transform', `translate(${radius + margin},${radius + margin})`)
+ .attr('transform', `translate(${radius + margin}, ${radius + margin})`)
.call(tron.led);
// good
const leds = stage.selectAll('.led').data(data);
+ const svg = leds.enter().append('svg:svg');
+ svg.classed('led', true).attr('width', (radius + margin) * 2);
+ const g = svg.append('svg:g');
+ g.attr('transform', `translate(${radius + margin}, ${radius + margin})`).call(tron.led);
```
-
- - [19.7](#whitespace--after-blocks) Leave a blank line after blocks and before the next statement.
+
+
+ - [19.7](#whitespace--after-blocks) 在一个代码块后下一条语句前空一行。
```javascript
// bad
@@ -2617,8 +2956,9 @@ Other Style Guides
return arr;
```
-
- - [19.8](#whitespace--padded-blocks) Do not pad your blocks with blank lines. eslint: [`padded-blocks`](https://eslint.org/docs/rules/padded-blocks.html)
+
+
+ - [19.8](#whitespace--padded-blocks) 不要用空白行填充块。eslint: [`padded-blocks`](http://eslint.org/docs/rules/padded-blocks)
```javascript
// bad
@@ -2628,23 +2968,15 @@ Other Style Guides
}
- // bad
+ // also bad
if (baz) {
- console.log(qux);
+ console.log(quux);
} else {
console.log(foo);
}
- // bad
- class Foo {
-
- constructor(bar) {
- this.bar = bar;
- }
- }
-
// good
function bar() {
console.log(foo);
@@ -2652,14 +2984,70 @@ Other Style Guides
// good
if (baz) {
- console.log(qux);
+ console.log(quux);
} else {
console.log(foo);
}
```
-
- - [19.9](#whitespace--in-parens) Do not add spaces inside parentheses. eslint: [`space-in-parens`](https://eslint.org/docs/rules/space-in-parens.html)
+
+ - [19.9](#whitespace--no-multiple-blanks) 不要在代码之间使用多个空白行填充。eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)
+
+
+ ```javascript
+ // 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) {
+ // ..
+ }
+ }
+ ```
+
+
+
+
+ - [19.10](#whitespace--in-parens) 圆括号里不要加空格。eslint: [`space-in-parens`](http://eslint.org/docs/rules/space-in-parens)
```javascript
// bad
@@ -2683,21 +3071,23 @@ Other Style Guides
}
```
-
- - [19.10](#whitespace--in-brackets) Do not add spaces inside brackets. eslint: [`array-bracket-spacing`](https://eslint.org/docs/rules/array-bracket-spacing.html)
+
+
+ - [19.11](#whitespace--in-brackets) 方括号里不要加空格。 eslint: [`array-bracket-spacing`](http://eslint.org/docs/rules/array-bracket-spacing)
```javascript
// bad
const foo = [ 1, 2, 3 ];
console.log(foo[ 0 ]);
- // good
+ // good,逗号分隔符后还是要空格的。
const foo = [1, 2, 3];
console.log(foo[0]);
```
-
- - [19.11](#whitespace--in-braces) Add spaces inside curly braces. eslint: [`object-curly-spacing`](https://eslint.org/docs/rules/object-curly-spacing.html)
+
+
+ - [19.12](#whitespace--in-braces) 花括号里加空格 。eslint: [`object-curly-spacing`](http://eslint.org/docs/rules/object-curly-spacing)
```javascript
// bad
@@ -2707,10 +3097,12 @@ Other Style Guides
const foo = { clark: 'kent' };
```
-
- - [19.12](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace). Note: per [above](#strings--line-length), long strings are exempt from this rule, and should not be broken up. eslint: [`max-len`](https://eslint.org/docs/rules/max-len.html)
+
+
- > Why? This ensures readability and maintainability.
+ - [19.13](#whitespace--max-len) 避免一行代码超过100个字符(包含空格)。注意:对于 [上面](#strings--line-length),长字符串不受此规则限制,不应换行。 eslint: [`max-len`](http://eslint.org/docs/rules/max-len)
+
+ > 为什么?这样确保可读性和可维护性。
```javascript
// bad
@@ -2727,6 +3119,14 @@ Other Style Guides
&& jsonData.foo.bar.baz.quux
&& jsonData.foo.bar.baz.quux.xyzzy;
+ // better
+ const foo = jsonData
+ ?.foo
+ ?.bar
+ ?.baz
+ ?.quux
+ ?.xyzzy;
+
// good
$.ajax({
method: 'POST',
@@ -2737,8 +3137,10 @@ Other Style Guides
.fail(() => console.log('You have failed this city.'));
```
+
- - [19.13](#whitespace--block-spacing) Require consistent spacing inside an open block token and the next token on the same line. This rule also enforces consistent spacing inside a close block token and previous token on the same line. eslint: [`block-spacing`](https://eslint.org/docs/rules/block-spacing)
+
+ - [19.14](#whitespace--block-spacing) 作为语句的花括号内也要加空格 —— `{` 后和 `}` 前都需要空格。 eslint: [`block-spacing`](https://eslint.org/docs/rules/block-spacing)
```javascript
// bad
@@ -2750,38 +3152,43 @@ Other Style Guides
if (foo) { bar = 0; }
```
+
- - [19.14](#whitespace--comma-spacing) Avoid spaces before commas and require a space after commas. eslint: [`comma-spacing`](https://eslint.org/docs/rules/comma-spacing)
+ - [19.15](#whitespace--comma-spacing) `,` 前不要空格, `,` 后需要空格。 eslint: [`comma-spacing`](https://eslint.org/docs/rules/comma-spacing)
```javascript
// bad
- var foo = 1,bar = 2;
- var arr = [1 , 2];
+ const foo = 1,bar = 2;
+ const arr = [1 , 2];
// good
- var foo = 1, bar = 2;
- var arr = [1, 2];
+ const foo = 1, bar = 2;
+ const arr = [1, 2];
```
+
- - [19.15](#whitespace--computed-property-spacing) Enforce spacing inside of computed properties. eslint: [`computed-property-spacing`](https://eslint.org/docs/rules/computed-property-spacing)
+ - [19.16](#whitespace--computed-property-spacing) 花括号跟属性间要有空格,中括号跟属性间没有空格。 eslint: [`computed-property-spacing`](https://eslint.org/docs/rules/computed-property-spacing)
+
+ 译者注:以代码为准。
```javascript
// bad
obj[foo ]
obj[ 'foo']
- var x = {[ b ]: a}
+ const x = {[ b ]: a}
obj[foo[ bar ]]
// good
obj[foo]
obj['foo']
- var x = { [b]: a }
+ const x = { [b]: a }
obj[foo[bar]]
```
+
- - [19.16](#whitespace--func-call-spacing) Enforce spacing between functions and their invocations. eslint: [`func-call-spacing`](https://eslint.org/docs/rules/func-call-spacing)
+ - [19.17](#whitespace--func-call-spacing) 调用函数时,函数名和小括号之间不要空格。 eslint: [`func-call-spacing`](https://eslint.org/docs/rules/func-call-spacing)
```javascript
// bad
@@ -2794,46 +3201,61 @@ Other Style Guides
func();
```
+
- - [19.17](#whitespace--key-spacing) Enforce spacing between keys and values in object literal properties. eslint: [`key-spacing`](https://eslint.org/docs/rules/key-spacing)
+ - [19.18](#whitespace--key-spacing) 在对象的字面量属性中, `key` 和 `value` 之间要有空格。 eslint: [`key-spacing`](https://eslint.org/docs/rules/key-spacing)
```javascript
// bad
- var obj = { "foo" : 42 };
- var obj2 = { "foo":42 };
+ const obj = { foo : 42 };
+ const obj2 = { foo:42 };
// good
- var obj = { "foo": 42 };
+ const obj = { foo: 42 };
```
+
- - [19.18](#whitespace--no-trailing-spaces) Avoid trailing spaces at the end of lines. eslint: [`no-trailing-spaces`](https://eslint.org/docs/rules/no-trailing-spaces)
+ - [19.19](#whitespace--no-trailing-spaces) 行末不要空格。 eslint: [`no-trailing-spaces`](https://eslint.org/docs/rules/no-trailing-spaces)
+
+
- - [19.19](#whitespace--no-multiple-empty-lines) Avoid multiple empty lines and only allow one newline at the end of files. eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)
+
+ - [19.20](#whitespace--no-multiple-empty-lines) 避免出现多个空行。 在文件末尾只允许空一行。文件开始处不要出现空行。eslint: [`no-multiple-empty-lines`](https://eslint.org/docs/rules/no-multiple-empty-lines)
```javascript
- // bad
- var x = 1;
+ // bad - multiple empty lines
+ const x = 1;
+
+
+ const y = 2;
+ // bad - 2+ newlines at end of file
+ const x = 1;
+ const y = 2;
- var y = 2;
+ // bad - 1+ newline(s) at beginning of file
+
+ const x = 1;
+ const y = 2;
// good
- var x = 1;
+ const x = 1;
+ const y = 2;
- var y = 2;
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Commas
+## 逗号
-
- - [20.1](#commas--leading-trailing) Leading commas: **Nope.** eslint: [`comma-style`](https://eslint.org/docs/rules/comma-style.html)
+
+
+ - [20.1](#commas--leading-trailing) 不要前置逗号。eslint: [`comma-style`](http://eslint.org/docs/rules/comma-style)
```javascript
// bad
@@ -2867,13 +3289,15 @@ Other Style Guides
};
```
-
- - [20.2](#commas--dangling) Additional trailing comma: **Yup.** eslint: [`comma-dangle`](https://eslint.org/docs/rules/comma-dangle.html)
+
+
+
+ - [20.2](#commas--dangling) 额外结尾逗号: **要** eslint: [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle)
- > Why? This leads to cleaner git diffs. Also, transpilers like Babel will remove the additional trailing comma in the transpiled code which means you don’t have to worry about the [trailing comma problem](https://github.com/airbnb/javascript/blob/es5-deprecated/es5/README.md#commas) in legacy browsers.
+ > 为什么?这使 git diffs 更简洁。此外,像Babel这样的转换器会删除转换代码中的额外的逗号,这意味着你不必担心旧版浏览器中的 [结尾逗号问题](https://github.com/airbnb/javascript/blob/es5-deprecated/es5/README.md#commas)。
```diff
- // bad - git diff without trailing comma
+ // bad - 没有结尾逗号的 git diff
const hero = {
firstName: 'Florence',
- lastName: 'Nightingale'
@@ -2881,7 +3305,7 @@ Other Style Guides
+ inventorOf: ['coxcomb chart', 'modern nursing']
};
- // good - git diff with trailing comma
+ // good - 有结尾逗号的 git diff
const hero = {
firstName: 'Florence',
lastName: 'Nightingale',
@@ -2930,7 +3354,7 @@ Other Style Guides
// does nothing
}
- // good (note that a comma must not appear after a "rest" element)
+ // good (注意,逗号不应出现在使用了 ... 操作符后的参数后面)
function createHero(
firstName,
lastName,
@@ -2954,38 +3378,39 @@ Other Style Guides
inventorOf,
);
- // good (note that a comma must not appear after a "rest" element)
+ // good (注意,逗号不应出现在使用了 ... 操作符后的参数后面)
createHero(
firstName,
lastName,
inventorOf,
...heroArgs
- );
+ )
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Semicolons
-
- - [21.1](#semicolons--required) **Yup.** eslint: [`semi`](https://eslint.org/docs/rules/semi.html)
+## 分号
- > Why? When JavaScript encounters a line break without a semicolon, it uses a set of rules called [Automatic Semicolon Insertion](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) to determine whether or not it should regard that line break as the end of a statement, and (as the name implies) place a semicolon into your code before the line break if it thinks so. ASI contains a few eccentric behaviors, though, and your code will break if JavaScript misinterprets your line break. These rules will become more complicated as new features become a part of JavaScript. Explicitly terminating your statements and configuring your linter to catch missing semicolons will help prevent you from encountering issues.
+
+ - [21.1](#21.1) **要分号!** eslint: [`semi`](http://eslint.org/docs/rules/semi)
+
+ > 为什么?当 JavaScript 遇到没有分号结尾的一行,它会执行 [自动插入分号](https://tc39.github.io/ecma262/#sec-automatic-semicolon-insertion) 这一规则来决定行末是否加分号。如果 JavaScript 在你的断行里错误的插入了分号,就会出现一些古怪的行为。当新的功能加到JavaScript 里后, 这些规则会变得更复杂难懂。清晰的结束语句,并通过配置代码检查去检查没有带分号的地方可以帮助你防止这种错误。
```javascript
- // bad - raises exception
+ // bad - 抛出异常
const luke = {}
const leia = {}
- [luke, leia].forEach(jedi => jedi.father = 'vader')
+ [luke, leia].forEach((jedi) => jedi.father = 'vader')
- // bad - raises exception
- const reaction = "No! That’s impossible!"
+ // bad - 抛出异常
+ const reaction = 'No! That’s impossible!'
(async function meanwhileOnTheFalcon() {
- // handle `leia`, `lando`, `chewie`, `r2`, `c3p0`
+ // 处理 `leia`, `lando`, `chewie`, `r2`, `c3p0`
// ...
}())
- // bad - returns `undefined` instead of the value on the next line - always happens when `return` is on a line by itself because of ASI!
+ // bad - 将返回 `undefined` 而不是下一行的值。由于 ASI,当 `return`单独出现在一行时,这种情况会一直出现。
function foo() {
return
'search your feelings, you know it to be foo'
@@ -3011,17 +3436,21 @@ Other Style Guides
}
```
- [Read more](https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214#7365214).
+ [更多](https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214%237365214).
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Type Casting & Coercion
-
- - [22.1](#coercion--explicit) Perform type coercion at the beginning of the statement.
+## 类型转换与强制转换
-
- - [22.2](#coercion--strings) Strings: eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
+
+
+ - [22.1](#coercion--explicit) 在语句开始执行强制类型转换。
+
+
+
+
+ - [22.2](#coercion--strings) 字符串: eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
```javascript
// => this.reviewScore = 9;
@@ -3030,17 +3459,23 @@ Other Style Guides
const totalScore = new String(this.reviewScore); // typeof totalScore is "object" not "string"
// bad
- const totalScore = this.reviewScore + ''; // invokes this.reviewScore.valueOf()
+ const totalScore = this.reviewScore + ''; // 将会执行 this.reviewScore.valueOf()
// bad
- const totalScore = this.reviewScore.toString(); // isn’t guaranteed to return a string
+ const totalScore = this.reviewScore.toString(); // 不保证返回 string
// good
const totalScore = String(this.reviewScore);
```
-
- - [22.3](#coercion--numbers) Numbers: Use `Number` for type casting and `parseInt` always with a radix for parsing strings. eslint: [`radix`](https://eslint.org/docs/rules/radix) [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
+
+
+
+ - [22.3](#coercion--numbers) 数字: 用 `Number` 做类型转换,`parseInt` 转换 `string` 应总是带上基数。 eslint: [`radix`](http://eslint.org/docs/rules/radix)
+
+ > 为什么?函数 `parseInt` 会根据指定的基数将字符串转换为数字。字符串开头的空白字符将会被忽略,如果参数基数(第二个参数)为 `undefined` 或者 `0` ,除非字符串开头为 `0x` 或 `0X`(十六进制),会默认假设为 `10`。这个差异来自 ECMAScript 3,它不鼓励(但是允许)解释八进制。在 2013 年之前,一些实现不兼容这种行为。因为我们需要支持旧浏览器,所以应当始终指定进制。
+
+ > 译者注:翻译的可能不是很好,总之使用 `parseInt()` 时始终指定进制数(第二个参数)就可以了。
```javascript
const inputValue = '4';
@@ -3064,30 +3499,33 @@ Other Style Guides
const val = parseInt(inputValue, 10);
```
-
- - [22.4](#coercion--comment-deviations) If for whatever reason you are doing something wild and `parseInt` is your bottleneck and need to use Bitshift for [performance reasons](https://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you’re doing.
+
+
+ - [22.4](#coercion--comment-deviations) 请在注释中解释为什么要用移位运算和你在做什么。无论你做什么狂野的事,比如由于 `parseInt` 是你的性能瓶颈导致你一定要用移位运算。说明这个是因为 [性能原因](https://jsperf.com/coercion-vs-casting/3)。
```javascript
// good
/**
- * parseInt was the reason my code was slow.
- * Bitshifting the String to coerce it to a
- * Number made it a lot faster.
+ * parseInt 是代码运行慢的原因
+ * 用 Bitshifting 将字符串转成数字使代码运行效率大幅提升
*/
const val = inputValue >> 0;
```
-
- - [22.5](#coercion--bitwise) **Note:** Be careful when using bitshift operations. Numbers are represented as [64-bit values](https://es5.github.io/#x4.3.19), but bitshift operations always return a 32-bit integer ([source](https://es5.github.io/#x11.7)). Bitshift can lead to unexpected behavior for integer values larger than 32 bits. [Discussion](https://github.com/airbnb/javascript/issues/109). Largest signed 32-bit Int is 2,147,483,647:
+
+
+
+ - [22.5](#coercion--bitwise) **注意:** 用移位运算要小心。数字是用 [64-位](https://es5.github.io/#x4.3.19)表示的,但移位运算常常返回的是32为整形[source](https://es5.github.io/#x11.7))。移位运算对大于 32 位的整数会导致意外行为。[Discussion](https://github.com/airbnb/javascript/issues/109). 最大的 32 位整数是 2,147,483,647:
```javascript
- 2147483647 >> 0; // => 2147483647
- 2147483648 >> 0; // => -2147483648
- 2147483649 >> 0; // => -2147483647
+ 2147483647 >> 0 //=> 2147483647
+ 2147483648 >> 0 //=> -2147483648
+ 2147483649 >> 0 //=> -2147483647
```
-
- - [22.6](#coercion--booleans) Booleans: eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
+
+
+ - [22.6](#coercion--booleans) 布尔: eslint: [`no-new-wrappers`](https://eslint.org/docs/rules/no-new-wrappers)
```javascript
const age = 0;
@@ -3102,12 +3540,14 @@ Other Style Guides
const hasAge = !!age;
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
+
-## Naming Conventions
+## 命名规范
-
- - [23.1](#naming--descriptive) Avoid single letter names. Be descriptive with your naming. eslint: [`id-length`](https://eslint.org/docs/rules/id-length)
+
+
+ - [23.1](#naming--descriptive) 避免用一个字母命名,让你的命名有意义。eslint: [`id-length`](http://eslint.org/docs/rules/id-length)
```javascript
// bad
@@ -3121,8 +3561,9 @@ Other Style Guides
}
```
-
- - [23.2](#naming--camelCase) Use camelCase when naming objects, functions, and instances. eslint: [`camelcase`](https://eslint.org/docs/rules/camelcase.html)
+
+
+ - [23.2](#naming--camelCase) 用小驼峰命名法来命名你的对象、函数、实例。eslint: [`camelcase`](http://eslint.org/docs/rules/camelcase)
```javascript
// bad
@@ -3135,8 +3576,9 @@ Other Style Guides
function thisIsMyFunction() {}
```
-
- - [23.3](#naming--PascalCase) Use PascalCase only when naming constructors or classes. eslint: [`new-cap`](https://eslint.org/docs/rules/new-cap.html)
+
+
+ - [23.3](#naming--PascalCase) 用大驼峰命名法来命名类。eslint: [`new-cap`](http://eslint.org/docs/rules/new-cap)
```javascript
// bad
@@ -3160,28 +3602,30 @@ Other Style Guides
});
```
-
- - [23.4](#naming--leading-underscore) Do not use trailing or leading underscores. eslint: [`no-underscore-dangle`](https://eslint.org/docs/rules/no-underscore-dangle.html)
+
+
+ - [23.4](#naming--leading-underscore) 不要用前置或后置下划线。eslint: [`no-underscore-dangle`](http://eslint.org/docs/rules/no-underscore-dangle)
- > Why? JavaScript does not have the concept of privacy in terms of properties or methods. Although a leading underscore is a common convention to mean “private”, in fact, these properties are fully public, and as such, are part of your public API contract. This convention might lead developers to wrongly think that a change won’t count as breaking, or that tests aren’t needed. tl;dr: if you want something to be “private”, it must not be observably present.
+ > 为什么?JavaScript 没有私有属性或私有方法的概念。尽管前置下划线通常的概念上意味着私有,事实上,这些属性是完全公有的,因此这部分也是你的 API 的内容。这一概念可能会导致开发者误以为更改这个不会导致崩溃或者不需要测试。如果你想要什么东西变成私有,那就不要让它在这里出现。
```javascript
- // bad
+ // 不好的
this.__firstName__ = 'Panda';
this.firstName_ = 'Panda';
this._firstName = 'Panda';
- // good
+ // 好的
this.firstName = 'Panda';
- // good, in environments where WeakMaps are available
- // see https://kangax.github.io/compat-table/es6/#test-WeakMap
+ // 好的, 在支持 WeakMaps 环境中可用
+ // 见 https://compat-table.github.io/compat-table/es6/#test-WeakMap
const firstNames = new WeakMap();
firstNames.set(this, 'Panda');
```
-
- - [23.5](#naming--self-this) Don’t save references to `this`. Use arrow functions or [Function#bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
+
+
+ - [23.5](#naming--self-this) 不要保存引用 `this`,用箭头函数或 [函数绑定——Function#bind](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind)。
```javascript
// bad
@@ -3208,8 +3652,10 @@ Other Style Guides
}
```
-
- - [23.6](#naming--filename-matches-export) A base filename should exactly match the name of its default export.
+
+
+
+ - [23.6](#naming--filename-matches-export) `export default` 导出模块A,则这个文件名也叫 `A.*`, `import` 时候的参数也叫 `A`。 大小写完全一致。
```javascript
// file 1 contents
@@ -3244,8 +3690,9 @@ Other Style Guides
// ^ supports both insideDirectory.js and insideDirectory/index.js
```
-
- - [23.7](#naming--camelCase-default-export) Use camelCase when you export-default a function. Your filename should be identical to your function’s name.
+
+
+ - [23.7](#naming--camelCase-default-export) 当你 export-default 一个函数时,函数名用小驼峰,文件名需要和函数名一致。
```javascript
function makeStyleGuide() {
@@ -3255,22 +3702,25 @@ Other Style Guides
export default makeStyleGuide;
```
-
- - [23.8](#naming--PascalCase-singleton) Use PascalCase when you export a constructor / class / singleton / function library / bare object.
+
+
+
+ - [23.8](#naming--PascalCase-singleton) 当你 export 一个结构体/类/单例/函数库/对象 时用大驼峰。
```javascript
const AirbnbStyleGuide = {
es6: {
- },
+ }
};
export default AirbnbStyleGuide;
```
+
- - [23.9](#naming--Acronyms-and-Initialisms) Acronyms and initialisms should always be all capitalized, or all lowercased.
+ - [23.9](#naming--Acronyms-and-Initialisms) 简称和缩写应该全部大写或全部小写。
- > Why? Names are for readability, not to appease a computer algorithm.
+ > 为什么?名字都是给人读的,不是为了去适应计算机算法。
```javascript
// bad
@@ -3303,12 +3753,18 @@ Other Style Guides
];
```
+
- - [23.10](#naming--uppercase) You may optionally uppercase a constant only if it (1) is exported, (2) is a `const` (it can not be reassigned), and (3) the programmer can trust it (and its nested properties) to never change.
+ - [23.10](#naming--uppercase) 你可以用全大写字母设置静态变量,他需要满足三个条件。
+
+ 1. 导出变量;
+ 1. 是 `const` 定义的, 保证不能被改变;
+ 1. 这个变量是可信的,他的子属性都是不能被改变的。
- > Why? This is an additional tool to assist in situations where the programmer would be unsure if a variable might ever change. UPPERCASE_VARIABLES are letting the programmer know that they can trust the variable (and its properties) not to change.
- - What about all `const` variables? - This is unnecessary, so uppercasing should not be used for constants within a file. It should be used for exported constants however.
- - What about exported objects? - Uppercase at the top level of export (e.g. `EXPORTED_OBJECT.key`) and maintain that all nested properties do not change.
+ > 为什么?这是一个附加工具,帮助开发者去辨识一个变量是不是不可变的。UPPERCASE_VARIABLES 能让开发者知道他能确信这个变量(以及他的属性)是不会变的。
+
+ - 对于所有的 `const` 变量呢? —— 这个是不必要的。大写变量不应该在同一个文件里定义并使用, 它只能用来作为导出变量。
+ - 那导出的对象呢? —— 大写变量处在 `export` 的最高级(例如:`EXPORTED_OBJECT.key`) 并且他包含的所有子属性都是不可变的。(译者注:即导出的变量是全大写的,但他的属性不用大写)
```javascript
// bad
@@ -3320,17 +3776,18 @@ Other Style Guides
// bad
export let REASSIGNABLE_VARIABLE = 'do not use let with uppercase variables';
+
// ---
- // allowed but does not supply semantic value
+ // 允许但不够语义化
export const apiKey = 'SOMEKEY';
- // better in most cases
+ // 在大多数情况下更好
export const API_KEY = 'SOMEKEY';
// ---
- // bad - unnecessarily uppercases key while adding no semantic value
+ // bad - 不必要的大写键,没有增加任何语义
export const MAPPING = {
KEY: 'value'
};
@@ -3341,15 +3798,19 @@ Other Style Guides
};
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
+
+
+## Get-Set 访问器
-## Accessors
+
+
+ - [24.1](#accessors--not-required) 不需要使用属性的访问器函数。
-
- - [24.1](#accessors--not-required) Accessor functions for properties are not required.
+
+
-
- - [24.2](#accessors--no-getters-setters) Do not use JavaScript getters/setters as they cause unexpected side effects and are harder to test, maintain, and reason about. Instead, if you do make accessor functions, use `getVal()` and `setVal('hello')`.
+ - [24.2](#accessors--no-getters-setters) 不要使用 JavaScript 的 getters/setters,因为他们会产生副作用,并且难以测试、维护和理解。相反的,你可以用 `getVal()` 和 `setVal('hello')` 去创造你自己的访问器函数。
```javascript
// bad
@@ -3375,8 +3836,9 @@ Other Style Guides
}
```
-
- - [24.3](#accessors--boolean-prefix) If the property/method is a `boolean`, use `isVal()` or `hasVal()`.
+
+
+ - [24.3](#accessors--boolean-prefix) 如果属性/方法是 `boolean`, 用 `isVal()` 或 `hasVal()`。
```javascript
// bad
@@ -3390,8 +3852,9 @@ Other Style Guides
}
```
-
- - [24.4](#accessors--consistent) It’s okay to create `get()` and `set()` functions, but be consistent.
+
+
+ - [24.4](#accessors--consistent) 用 `get() ` 和 `set()` 函数是可以的,但是要一起用。
```javascript
class Jedi {
@@ -3410,12 +3873,14 @@ Other Style Guides
}
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
-## Events
-
- - [25.1](#events--hash) When attaching data payloads to events (whether DOM events or something more proprietary like Backbone events), pass an object literal (also known as a "hash") instead of a raw value. This allows a subsequent contributor to add more data to the event payload without finding and updating every handler for the event. For example, instead of:
+## 事件
+
+
+
+ - [25.1](#events--hash) 当传递数据载荷给事件时(不论是 DOM 还是像 Backbone 这样有很多属性的事件)。这使得后续的贡献者(程序员)向这个事件添加更多的数据时不用去找或者更新每个处理器。例如:
```javascript
// bad
@@ -3441,12 +3906,14 @@ Other Style Guides
});
```
- **[⬆ back to top](#table-of-contents)**
+**[⬆ 返回顶部](#目录)**
+
## jQuery
-
- - [26.1](#jquery--dollar-prefix) Prefix jQuery object variables with a `$`.
+
+
+ - [26.1](#jquery--dollar-prefix) jQuery 对象用`$`变量表示。
```javascript
// bad
@@ -3459,8 +3926,9 @@ Other Style Guides
const $sidebarBtn = $('.sidebar-btn');
```
-
- - [26.2](#jquery--cache) Cache jQuery lookups.
+
+
+ - [26.2](#jquery--cache) 缓存 jQuery 查找。
```javascript
// bad
@@ -3470,7 +3938,7 @@ Other Style Guides
// ...
$('.sidebar').css({
- 'background-color': 'pink',
+ 'background-color': 'pink'
});
}
@@ -3482,16 +3950,18 @@ Other Style Guides
// ...
$sidebar.css({
- 'background-color': 'pink',
+ 'background-color': 'pink'
});
}
```
-
- - [26.3](#jquery--queries) For DOM queries use Cascading `$('.sidebar ul')` or parent > child `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
+
+
+ - [26.3](#jquery--queries) DOM 查找用层叠式`$('.sidebar ul')` 或 父节点 > 子节点 `$('.sidebar > ul')`. [jsPerf](http://jsperf.com/jquery-find-vs-context-sel/16)
-
- - [26.4](#jquery--find) Use `find` with scoped jQuery object queries.
+
+
+ - [26.4](#jquery--find) 用 jQuery 对象查询作用域的 `find` 方法查询。
```javascript
// bad
@@ -3510,54 +3980,57 @@ Other Style Guides
$sidebar.find('ul').hide();
```
-**[⬆ back to top](#table-of-contents)**
+**[⬆ back to top](#目录)**
-## ECMAScript 5 Compatibility
-
- - [27.1](#es5-compat--kangax) Refer to [Kangax](https://twitter.com/kangax/)’s ES5 [compatibility table](https://kangax.github.io/es5-compat-table/).
+## ECMAScript 5 兼容性
-**[⬆ back to top](#table-of-contents)**
+
+
+ - [27.1](#es5-compat--kangax) 参考 [Kangax](https://twitter.com/kangax/) 的 ES5 [兼容性列表](https://compat-table.github.io/compat-table/es6/).
-
-## ECMAScript 6+ (ES 2015+) Styles
+**[⬆ 返回顶部](#目录)**
-
- - [28.1](#es6-styles) This is a collection of links to the various ES6+ features.
+## ECMAScript 6+ (ES 2015+) 风格
-1. [Arrow Functions](#arrow-functions)
-1. [Classes](#classes--constructors)
-1. [Object Shorthand](#es6-object-shorthand)
-1. [Object Concise](#es6-object-concise)
-1. [Object Computed Properties](#es6-computed-properties)
-1. [Template Strings](#es6-template-literals)
-1. [Destructuring](#destructuring)
-1. [Default Parameters](#es6-default-parameters)
-1. [Rest](#es6-rest)
-1. [Array Spreads](#es6-array-spreads)
+
+
+ - [28.1](#es6-styles) 这是收集到的各种ES6特性的链接
+
+1. [箭头函数——Arrow Functions](#arrow-functions)
+1. [类——Classes](#classes--constructors)
+1. [对象缩写——Object Shorthand](#es6-object-shorthand)
+1. [对象简写——Object Concise](#es6-object-concise)
+1. [对象计算属性——Object Computed Properties](#es6-computed-properties)
+1. [模板字符串——Template Strings](#es6-template-literals)
+1. [解构赋值——Destructuring](#destructuring)
+1. [默认参数——Default Parameters](#es6-default-parameters)
+1. [剩余参数——Rest](#es6-rest)
+1. [数组拓展——Array Spreads](#es6-array-spreads)
1. [Let and Const](#references)
-1. [Exponentiation Operator](#es2016-properties--exponentiation-operator)
-1. [Iterators and Generators](#iterators-and-generators)
-1. [Modules](#modules)
+1. [幂操作符——Exponentiation Operator](#es2016-properties--exponentiation-operator)
+1. [迭代器和生成器——Iterators and Generators](#iterators-and-generators)
+1. [模块——Modules](#modules)
+
- - [28.2](#tc39-proposals) Do not use [TC39 proposals](https://github.com/tc39/proposals) that have not reached stage 3.
+ - [28.2](#tc39-proposals) 不要用 [TC39 proposals](https://github.com/tc39/proposals), TC39 还没有到 stage 3。
- > Why? [They are not finalized](https://tc39.github.io/process-document/), and they are subject to change or to be withdrawn entirely. We want to use JavaScript, and proposals are not JavaScript yet.
+ > 为什么? [它还不是最终版](https://tc39.github.io/process-document/), 他可能还有很多变化,或者被撤销。我们想要用的是 JavaScript, 提议还不是 JavaScript。
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 回到顶部](#目录)**
-## Standard Library
+## 标准库
- The [Standard Library](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects)
- contains utilities that are functionally broken but remain for legacy reasons.
+ [标准库](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects)中包含一些功能受损但是由于历史原因遗留的工具类
+
- - [29.1](#standard-library--isnan) Use `Number.isNaN` instead of global `isNaN`.
+ - [29.1](#standard-library--isnan) 用 `Number.isNaN` 代替全局的 `isNaN`。
eslint: [`no-restricted-globals`](https://eslint.org/docs/rules/no-restricted-globals)
- > Why? The global `isNaN` coerces non-numbers to numbers, returning true for anything that coerces to NaN.
- > If this behavior is desired, make it explicit.
+ > 为什么?全局 `isNaN` 强制把非数字转成数字, 然后对于任何强转后为 `NaN` 的变量都返回 `true`
+ > 如果你想用这个功能,就显式的用它。
```javascript
// bad
@@ -3569,12 +4042,12 @@ Other Style Guides
Number.isNaN(Number('1.2.3')); // true
```
+
- - [29.2](#standard-library--isfinite) Use `Number.isFinite` instead of global `isFinite`.
+ - [29.2](#standard-library--isfinite) 用 `Number.isFinite` 代替 `isFinite`.
eslint: [`no-restricted-globals`](https://eslint.org/docs/rules/no-restricted-globals)
- > Why? The global `isFinite` coerces non-numbers to numbers, returning true for anything that coerces to a finite number.
- > If this behavior is desired, make it explicit.
+ > Why? 理由同上,会把一个非数字变量强转成数字,然后做判断。
```javascript
// bad
@@ -3585,11 +4058,10 @@ Other Style Guides
Number.isFinite(parseInt('2e3', 10)); // true
```
-**[⬆ back to top](#table-of-contents)**
-
-## Testing
+## 测试
-
+
+
- [30.1](#testing--yup) **Yup.**
```javascript
@@ -3598,54 +4070,58 @@ Other Style Guides
}
```
-
+
+
- [30.2](#testing--for-real) **No, but seriously**:
- - Whichever testing framework you use, you should be writing tests!
- - Strive to write many small pure functions, and minimize where mutations occur.
- - Be cautious about stubs and mocks - they can make your tests more brittle.
- - We primarily use [`mocha`](https://www.npmjs.com/package/mocha) and [`jest`](https://www.npmjs.com/package/jest) at Airbnb. [`tape`](https://www.npmjs.com/package/tape) is also used occasionally for small, separate modules.
- - 100% test coverage is a good goal to strive for, even if it’s not always practical to reach it.
- - Whenever you fix a bug, _write a regression test_. A bug fixed without a regression test is almost certainly going to break again in the future.
+ - 无论用哪个测试框架,你都需要写测试。
+ - 尽量去写很多小而美的纯函数,减少突变的发生
+ - 小心 stub 和 mock —— 这会让你的测试变得脆弱。
+ - 在 Airbnb 首选 [`mocha`](https://www.npmjs.com/package/mocha)。 [`tape`](https://www.npmjs.com/package/tape) 偶尔被用来测试一些小的、独立的模块。
+ - 100% 测试覆盖率是我们努力的目标,即便实际上很少达到。
+ - 每当你修了一个 bug,*都要写一个回归测试*。 一个 bug 修复了,没有回归测试,很可能以后会再次出问题。
-**[⬆ back to top](#table-of-contents)**
+**[⬆ 回到顶部](#目录)**
-## Performance
+
+## 性能
- [On Layout & Web Performance](https://www.kellegous.com/j/2013/01/26/layout-performance/)
- - [String vs Array Concat](https://jsperf.com/string-vs-array-concat/2)
- - [Try/Catch Cost In a Loop](https://jsperf.com/try-catch-in-loop-cost)
- - [Bang Function](https://jsperf.com/bang-function)
- - [jQuery Find vs Context, Selector](https://jsperf.com/jquery-find-vs-context-sel/13)
- - [innerHTML vs textContent for script text](https://jsperf.com/innerhtml-vs-textcontent-for-script-text)
- - [Long String Concatenation](https://jsperf.com/ya-string-concat)
- - [Are Javascript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta)
+ - [String vs Array Concat](https://web.archive.org/web/20200414200857/https://jsperf.com/string-vs-array-concat/2)
+ - [Try/Catch Cost In a Loop](https://web.archive.org/web/20200414190827/https://jsperf.com/try-catch-in-loop-cost/12)
+ - [Bang Function](https://web.archive.org/web/20200414205426/https://jsperf.com/bang-function)
+ - [jQuery Find vs Context, Selector](https://web.archive.org/web/20200414200850/https://jsperf.com/jquery-find-vs-context-sel/164)
+ - [innerHTML vs textContent for script text](https://web.archive.org/web/20200414205428/https://jsperf.com/innerhtml-vs-textcontent-for-script-text)
+ - [Long String Concatenation](https://web.archive.org/web/20200414203914/https://jsperf.com/ya-string-concat/38)
+ - [Are JavaScript functions like `map()`, `reduce()`, and `filter()` optimized for traversing arrays?](https://www.quora.com/JavaScript-programming-language-Are-Javascript-functions-like-map-reduce-and-filter-already-optimized-for-traversing-array/answer/Quildreen-Motta)
- Loading...
-**[⬆ back to top](#table-of-contents)**
+**[⬆ back to top](#目录)**
+
-## Resources
+## 资源
-**Learning ES6+**
+**Learning ES6**
- - [Latest ECMA spec](https://tc39.github.io/ecma262/)
- - [ExploringJS](http://exploringjs.com/)
+ - [Draft ECMA 2015 (ES6) Spec](https://people.mozilla.org/~jorendorff/es6-draft)
+ - [ExploringJS](https://exploringjs.com/)
- [ES6 Compatibility Table](https://kangax.github.io/compat-table/es6/)
- [Comprehensive Overview of ES6 Features](http://es6-features.org/)
**Read This**
- - [Standard ECMA-262](http://www.ecma-international.org/ecma-262/6.0/index.html)
+ - [Standard ECMA-262](https://www.ecma-international.org/ecma-262/6.0/index)
**Tools**
- Code Style Linters
- [ESlint](https://eslint.org/) - [Airbnb Style .eslintrc](https://github.com/airbnb/javascript/blob/master/linters/.eslintrc)
- - [JSHint](http://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc)
+ - [JSHint](https://jshint.com/) - [Airbnb Style .jshintrc](https://github.com/airbnb/javascript/blob/master/linters/.jshintrc)
- Neutrino Preset - [@neutrinojs/airbnb](https://neutrinojs.org/packages/airbnb/)
**Other Style Guides**
- - [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
+ - [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide)
+ - [Google JavaScript Style Guide (Old)](https://google.github.io/styleguide/javascriptguide.xml)
- [jQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/js/)
- [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js)
- [StandardJS](https://standardjs.com)
@@ -3660,8 +4136,8 @@ Other Style Guides
**Further Reading**
- [Understanding JavaScript Closures](https://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
- - [Basic JavaScript for the impatient programmer](http://www.2ality.com/2013/06/basic-javascript.html) - Dr. Axel Rauschmayer
- - [You Might Not Need jQuery](http://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
+ - [Basic JavaScript for the impatient programmer](https://www.2ality.com/2013/06/basic-javascript) - Dr. Axel Rauschmayer
+ - [You Might Not Need jQuery](https://youmightnotneedjquery.com/) - Zack Bloom & Adam Schwartz
- [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
- [Frontend Guidelines](https://github.com/bendc/frontend-guidelines) - Benjamin De Cock
@@ -3669,7 +4145,7 @@ Other Style Guides
- [JavaScript: The Good Parts](https://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
- [JavaScript Patterns](https://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
- - [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
+ - [Pro JavaScript Design Patterns](https://www.amazon.com/JavaScript-Design-Patterns-Recipes-Problem-Solution/dp/159059908X) - Ross Harmes and Dustin Diaz
- [High Performance Web Sites: Essential Knowledge for Front-End Engineers](https://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
- [Maintainable JavaScript](https://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
- [JavaScript Web Applications](https://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
@@ -3678,48 +4154,47 @@ Other Style Guides
- [Secrets of the JavaScript Ninja](https://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
- [Human JavaScript](http://humanjavascript.com/) - Henrik Joreteg
- [Superhero.js](http://superherojs.com/) - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
- - [JSBooks](http://jsbooks.revolunet.com/) - Julien Bouquillon
+ - [JSBooks](https://jsbooks.revolunet.com/) - Julien Bouquillon
- [Third Party JavaScript](https://www.manning.com/books/third-party-javascript) - Ben Vinegar and Anton Kovalyov
- - [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](http://amzn.com/0321812182) - David Herman
- - [Eloquent JavaScript](http://eloquentjavascript.net/) - Marijn Haverbeke
- - [You Don’t Know JS: ES6 & Beyond](http://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson
+ - [Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript](https://amzn.com/dp/0321812182) - David Herman
+ - [Eloquent JavaScript](https://eloquentjavascript.net/) - Marijn Haverbeke
+ - [You Don’t Know JS: ES6 & Beyond](https://shop.oreilly.com/product/0636920033769.do) - Kyle Simpson
**Blogs**
- - [JavaScript Weekly](http://javascriptweekly.com/)
+ - [JavaScript Weekly](https://javascriptweekly.com/)
- [JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/)
- [Bocoup Weblog](https://bocoup.com/weblog)
- - [Adequately Good](http://www.adequatelygood.com/)
+ - [Adequately Good](https://www.adequatelygood.com/)
- [NCZOnline](https://www.nczonline.net/)
- [Perfection Kills](http://perfectionkills.com/)
- - [Ben Alman](http://benalman.com/)
+ - [Ben Alman](https://benalman.com/)
- [Dmitry Baranovskiy](http://dmitry.baranovskiy.com/)
- - [nettuts](http://code.tutsplus.com/?s=javascript)
+ - [nettuts](https://code.tutsplus.com/?s=javascript)
**Podcasts**
- [JavaScript Air](https://javascriptair.com/)
- [JavaScript Jabber](https://devchat.tv/js-jabber/)
-**[⬆ back to top](#table-of-contents)**
+
+**[⬆ 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.
- **123erfasst**: [123erfasst/javascript](https://github.com/123erfasst/javascript)
- - **3blades**: [3Blades](https://github.com/3blades)
- **4Catalyzer**: [4Catalyzer/javascript](https://github.com/4Catalyzer/javascript)
- **Aan Zee**: [AanZee/javascript](https://github.com/AanZee/javascript)
- - **Adult Swim**: [adult-swim/javascript](https://github.com/adult-swim/javascript)
- **Airbnb**: [airbnb/javascript](https://github.com/airbnb/javascript)
+ - **AloPeyk**: [AloPeyk](https://github.com/AloPeyk)
- **AltSchool**: [AltSchool/javascript](https://github.com/AltSchool/javascript)
- **Apartmint**: [apartmint/javascript](https://github.com/apartmint/javascript)
- **Ascribe**: [ascribe/javascript](https://github.com/ascribe/javascript)
- - **Avalara**: [avalara/javascript](https://github.com/avalara/javascript)
- **Avant**: [avantcredit/javascript](https://github.com/avantcredit/javascript)
- **Axept**: [axept/javascript](https://github.com/axept/javascript)
- - **BashPros**: [BashPros/javascript](https://github.com/BashPros/javascript)
- **Billabong**: [billabong/javascript](https://github.com/billabong/javascript)
- **Bisk**: [bisk](https://github.com/Bisk/)
- **Bonhomme**: [bonhommeparis/javascript](https://github.com/bonhommeparis/javascript)
@@ -3727,18 +4202,18 @@ Other Style Guides
- **CaseNine**: [CaseNine/javascript](https://github.com/CaseNine/javascript)
- **Cerner**: [Cerner](https://github.com/cerner/)
- **Chartboost**: [ChartBoost/javascript-style-guide](https://github.com/ChartBoost/javascript-style-guide)
+ - **Coeur d'Alene Tribe**: [www.cdatribe-nsn.gov](https://www.cdatribe-nsn.gov)
- **ComparaOnline**: [comparaonline/javascript](https://github.com/comparaonline/javascript-style-guide)
- **Compass Learning**: [compasslearning/javascript-style-guide](https://github.com/compasslearning/javascript-style-guide)
- **DailyMotion**: [dailymotion/javascript](https://github.com/dailymotion/javascript)
- **DoSomething**: [DoSomething/eslint-config](https://github.com/DoSomething/eslint-config)
- **Digitpaint** [digitpaint/javascript](https://github.com/digitpaint/javascript)
- - **Drupal**: [www.drupal.org](https://www.drupal.org/project/drupal)
+ - **Drupal**: [www.drupal.org](https://git.drupalcode.org/project/drupal/blob/8.6.x/core/.eslintrc.json)
- **Ecosia**: [ecosia/javascript](https://github.com/ecosia/javascript)
- **Evernote**: [evernote/javascript-style-guide](https://github.com/evernote/javascript-style-guide)
- **Evolution Gaming**: [evolution-gaming/javascript](https://github.com/evolution-gaming/javascript)
- **EvozonJs**: [evozonjs/javascript](https://github.com/evozonjs/javascript)
- **ExactTarget**: [ExactTarget/javascript](https://github.com/ExactTarget/javascript)
- - **Expensify** [Expensify/Style-Guide](https://github.com/Expensify/Style-Guide/blob/master/javascript.md)
- **Flexberry**: [Flexberry/javascript-style-guide](https://github.com/Flexberry/javascript-style-guide)
- **Gawker Media**: [gawkermedia](https://github.com/gawkermedia/)
- **General Electric**: [GeneralElectric/javascript](https://github.com/GeneralElectric/javascript)
@@ -3747,14 +4222,13 @@ Other Style Guides
- **GreenChef**: [greenchef/javascript](https://github.com/greenchef/javascript)
- **Grooveshark**: [grooveshark/javascript](https://github.com/grooveshark/javascript)
- **Grupo-Abraxas**: [Grupo-Abraxas/javascript](https://github.com/Grupo-Abraxas/javascript)
+ - **Happeo**: [happeo/javascript](https://github.com/happeo/javascript)
- **Honey**: [honeyscience/javascript](https://github.com/honeyscience/javascript)
- **How About We**: [howaboutwe/javascript](https://github.com/howaboutwe/javascript-style-guide)
- - **Huballin**: [huballin](https://github.com/huballin/)
- **HubSpot**: [HubSpot/javascript](https://github.com/HubSpot/javascript)
- **Hyper**: [hyperoslo/javascript-playbook](https://github.com/hyperoslo/javascript-playbook/blob/master/style.md)
- **InterCity Group**: [intercitygroup/javascript-style-guide](https://github.com/intercitygroup/javascript-style-guide)
- **Jam3**: [Jam3/Javascript-Code-Conventions](https://github.com/Jam3/Javascript-Code-Conventions)
- - **JeopardyBot**: [kesne/jeopardy-bot](https://github.com/kesne/jeopardy-bot/blob/master/STYLEGUIDE.md)
- **JSSolutions**: [JSSolutions/javascript](https://github.com/JSSolutions/javascript)
- **Kaplan Komputing**: [kaplankomputing/javascript](https://github.com/kaplankomputing/javascript)
- **KickorStick**: [kickorstick](https://github.com/kickorstick/)
@@ -3765,24 +4239,19 @@ Other Style Guides
- **Mighty Spring**: [mightyspring/javascript](https://github.com/mightyspring/javascript)
- **MinnPost**: [MinnPost/javascript](https://github.com/MinnPost/javascript)
- **MitocGroup**: [MitocGroup/javascript](https://github.com/MitocGroup/javascript)
- - **ModCloth**: [modcloth/javascript](https://github.com/modcloth/javascript)
- - **Money Advice Service**: [moneyadviceservice/javascript](https://github.com/moneyadviceservice/javascript)
- **Muber**: [muber](https://github.com/muber/)
- - **National Geographic**: [natgeo](https://github.com/natgeo/)
- - **Nimbl3**: [nimbl3/javascript](https://github.com/nimbl3/javascript)
+ - **National Geographic Society**: [natgeosociety](https://github.com/natgeosociety/)
+ - **NullDev**: [NullDevCo/JavaScript-Styleguide](https://github.com/NullDevCo/JavaScript-Styleguide)
- **Nulogy**: [nulogy/javascript](https://github.com/nulogy/javascript)
- **Orange Hill Development**: [orangehill/javascript](https://github.com/orangehill/javascript)
- **Orion Health**: [orionhealth/javascript](https://github.com/orionhealth/javascript)
- - **OutBoxSoft**: [OutBoxSoft/javascript](https://github.com/OutBoxSoft/javascript)
- **Peerby**: [Peerby/javascript](https://github.com/Peerby/javascript)
+ - **Pier 1**: [Pier1/javascript](https://github.com/pier1/javascript)
- **Qotto**: [Qotto/javascript-style-guide](https://github.com/Qotto/javascript-style-guide)
- - **Razorfish**: [razorfish/javascript-style-guide](https://github.com/razorfish/javascript-style-guide)
- - **reddit**: [reddit/styleguide/javascript](https://github.com/reddit/styleguide/tree/master/javascript)
- - **React**: [facebook.github.io/react/contributing/how-to-contribute.html#style-guide](https://facebook.github.io/react/contributing/how-to-contribute.html#style-guide)
+ - **React**: [https://legacy.reactjs.org/docs/how-to-contribute.html#style-guide](https://legacy.reactjs.org/docs/how-to-contribute.html#style-guide)
- **REI**: [reidev/js-style-guide](https://github.com/rei/code-style-guides/)
- **Ripple**: [ripple/javascript-style-guide](https://github.com/ripple/javascript-style-guide)
- **Sainsbury’s Supermarkets**: [jsainsburyplc](https://github.com/jsainsburyplc)
- - **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide)
- **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript)
- **Sourcetoad**: [sourcetoad/javascript](https://github.com/sourcetoad/javascript)
- **Springload**: [springload](https://github.com/springload/)
@@ -3793,16 +4262,20 @@ Other Style Guides
- **SysGarage**: [sysgarage/javascript-style-guide](https://github.com/sysgarage/javascript-style-guide)
- **Syzygy Warsaw**: [syzygypl/javascript](https://github.com/syzygypl/javascript)
- **Target**: [target/javascript](https://github.com/target/javascript)
+ - **Terra**: [terra](https://github.com/cerner?utf8=%E2%9C%93&q=terra&type=&language=)
- **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript)
- **The Nerdery**: [thenerdery/javascript-standards](https://github.com/thenerdery/javascript-standards)
+ - **Tomify**: [tomprats](https://github.com/tomprats)
+ - **Traitify**: [traitify/eslint-config-traitify](https://github.com/traitify/eslint-config-traitify)
- **T4R Technology**: [T4R-Technology/javascript](https://github.com/T4R-Technology/javascript)
+ - **UrbanSim**: [urbansim](https://github.com/urbansim/)
- **VoxFeed**: [VoxFeed/javascript-style-guide](https://github.com/VoxFeed/javascript-style-guide)
- **WeBox Studio**: [weboxstudio/javascript](https://github.com/weboxstudio/javascript)
- **Weggo**: [Weggo/javascript](https://github.com/Weggo/javascript)
- **Zillow**: [zillow/javascript](https://github.com/zillow/javascript)
- **ZocDoc**: [ZocDoc/javascript](https://github.com/ZocDoc/javascript)
-**[⬆ back to top](#table-of-contents)**
+**[⬆ back to top](#目录)**
## Translation
@@ -3811,7 +4284,7 @@ Other Style Guides
-  **Brazilian Portuguese**: [armoucar/javascript-style-guide](https://github.com/armoucar/javascript-style-guide)
-  **Bulgarian**: [borislavvv/javascript](https://github.com/borislavvv/javascript)
-  **Catalan**: [fpmweb/javascript-style-guide](https://github.com/fpmweb/javascript-style-guide)
- -  **Chinese (Simplified)**: [yuche/javascript](https://github.com/yuche/javascript)
+ -  **Chinese (Simplified)**: [lin-123/javascript](https://github.com/lin-123/javascript)
-  **Chinese (Traditional)**: [jigsawye/javascript](https://github.com/jigsawye/javascript)
-  **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide)
-  **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide)
@@ -3823,7 +4296,7 @@ Other Style Guides
-  **Thai**: [lvarayut/javascript-style-guide](https://github.com/lvarayut/javascript-style-guide)
-  **Turkish**: [eraycetinay/javascript](https://github.com/eraycetinay/javascript)
-  **Ukrainian**: [ivanzusko/javascript](https://github.com/ivanzusko/javascript)
- -  **Vietnam**: [hngiang/javascript-style-guide](https://github.com/hngiang/javascript-style-guide)
+ -  **Vietnam**: [dangkyokhoang/javascript-style-guide](https://github.com/dangkyokhoang/javascript-style-guide)
## The JavaScript Style Guide Guide
@@ -3862,7 +4335,7 @@ 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](#table-of-contents)**
+**[⬆ back to top](#目录)**
## Amendments
diff --git a/react/README.md b/react/README.md
index 850373a129..e9e0b342a4 100644
--- a/react/README.md
+++ b/react/README.md
@@ -1,37 +1,41 @@
-# Airbnb React/JSX Style Guide
-
-*A mostly reasonable approach to React and JSX*
-
-This style guide is mostly based on the standards that are currently prevalent in JavaScript, although some conventions (i.e async/await or static class fields) may still be included or prohibited on a case-by-case basis. Currently, anything prior to stage 3 is not included nor recommended in this guide.
-
-## Table of Contents
-
- 1. [Basic Rules](#basic-rules)
- 1. [Class vs `React.createClass` vs stateless](#class-vs-reactcreateclass-vs-stateless)
- 1. [Mixins](#mixins)
- 1. [Naming](#naming)
- 1. [Declaration](#declaration)
- 1. [Alignment](#alignment)
- 1. [Quotes](#quotes)
- 1. [Spacing](#spacing)
- 1. [Props](#props)
- 1. [Refs](#refs)
- 1. [Parentheses](#parentheses)
- 1. [Tags](#tags)
- 1. [Methods](#methods)
- 1. [Ordering](#ordering)
- 1. [`isMounted`](#ismounted)
+# Airbnb React/JSX 风格指南
+
+*React 和 JSX 的最佳实践*
+
+这个指南大部分基于现在在JavaScript中流行的标准,尽管有些约定(如: async/await 或 class 的 static 字段)根据具体情况也会被引入或者被禁止。当前这个指南不包括也不推荐任何 ECMAScript stage-3(第三阶段提案) 之前的内容。
+
+## 目录
+
+- [Airbnb React/JSX 风格指南](#airbnb-reactjsx-风格指南)
+ - [目录](#目录)
+ - [Basic Rules](#basic-rules)
+ - [Class vs `React.createClass` vs stateless](#class-vs-reactcreateclass-vs-stateless)
+ - [Mixins](#mixins)
+ - [Naming](#naming)
+ - [Declaration](#declaration)
+ - [Alignment](#alignment)
+ - [Quotes](#quotes)
+ - [Spacing](#spacing)
+ - [Props](#props)
+ - [Refs](#refs)
+ - [Parentheses](#parentheses)
+ - [Tags](#tags)
+ - [Methods](#methods)
+ - [Ordering](#ordering)
+ - [`isMounted`](#ismounted)
+ - [Translation](#translation)
## Basic Rules
- - Only include one React component per file.
- - However, multiple [Stateless, or Pure, Components](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions) are allowed per file. eslint: [`react/no-multi-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless).
- - Always use JSX syntax.
- - Do not use `React.createElement` unless you’re initializing the app from a file that is not JSX.
+ - 每个文件只包含一个 React 组件
+ - 然而,在一个文件里包含多个[没有 state 或纯组件](https://facebook.github.io/react/docs/reusable-components.html#stateless-functions)是允许的。 eslint: [`react/no-multi-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-multi-comp.md#ignorestateless).
+ - 经常用 JSX 语法。
+ - 不要用 `React.createElement`, 除非你从一个非 JSX 文件中初始化 app。
+ - [`react/forbid-prop-types`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/forbid-prop-types.md) 只有在明确指定了数组和对象中包含的内容,使用 `arrayOf` 、 `objectOf` 或 `shape` 时才允许使用数组和对象。
## Class vs `React.createClass` vs stateless
- - If you have internal state and/or refs, prefer `class extends React.Component` over `React.createClass`. eslint: [`react/prefer-es6-class`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
+ - 如果你要用 state refs, 最好用 `class extends React.Component` 而不是 `React.createClass`。 eslint: [`react/prefer-es6-class`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-es6-class.md) [`react/prefer-stateless-function`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/prefer-stateless-function.md)
```jsx
// bad
@@ -51,7 +55,7 @@ This style guide is mostly based on the standards that are currently prevalent i
}
```
- And if you don’t have state or refs, prefer normal functions (not arrow functions) over classes:
+ 如果你没有使用 state、 refs ,最好用正常函数(不是箭头函数)而不是 class:
```jsx
// bad
@@ -61,7 +65,7 @@ This style guide is mostly based on the standards that are currently prevalent i
}
}
- // bad (relying on function name inference is discouraged)
+ // bad (不鼓励依赖函数名推断————relying on function name inference is discouraged)
const Listing = ({ hello }) => (
{hello}
);
@@ -74,15 +78,15 @@ This style guide is mostly based on the standards that are currently prevalent i
## Mixins
- - [Do not use mixins](https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html).
+ - [不要用 mixins](https://facebook.github.io/react/blog/2016/07/13/mixins-considered-harmful.html).
- > Why? Mixins introduce implicit dependencies, cause name clashes, and cause snowballing complexity. Most use cases for mixins can be accomplished in better ways via components, higher-order components, or utility modules.
+ > Why? mixins 会引入一些隐含依赖,导致命名冲突,会导致滚雪球式的复杂度。大多数情况下,mixins 都可以通过组件,[高阶组件 HOC](https://reactjs.org/docs/higher-order-components.html)或者工具模块更好的实现。
## Naming
- - **Extensions**: Use `.jsx` extension for React components.
- - **Filename**: Use PascalCase for filenames. E.g., `ReservationCard.jsx`.
- - **Reference Naming**: Use PascalCase for React components and camelCase for their instances. eslint: [`react/jsx-pascal-case`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md)
+ - **扩展名**: 用 `.jsx` 作为组件扩展名。eslint: eslint: [`react/jsx-filename-extension`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-filename-extension.md)
+ - **文件名**: 用大驼峰作为文件名,如:`ReservationCard.jsx`。
+ - **参数命名**: React 组件用大驼峰,组件的实例用小驼峰。 eslint: [`react/jsx-pascal-case`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-pascal-case.md)
```jsx
// bad
@@ -98,7 +102,7 @@ This style guide is mostly based on the standards that are currently prevalent i
const reservationItem = ;
```
- - **Component Naming**: Use the filename as the component name. For example, `ReservationCard.jsx` should have a reference name of `ReservationCard`. However, for root components of a directory, use `index.jsx` as the filename and use the directory name as the component name:
+ - **组件命名**: 文件名作为组件名。例如:`ReservationCard.jsx` 应该用 `ReservationCard` 作为参数名。 然而,对于一个文件夹里的跟组件,应该用 `index.jsx` 作为文件名,同时用文件夹名作为组件名
```jsx
// bad
@@ -110,9 +114,9 @@ This style guide is mostly based on the standards that are currently prevalent i
// good
import Footer from './Footer';
```
- - **Higher-order Component Naming**: Use a composite of the higher-order component’s name and the passed-in component’s name as the `displayName` on the generated component. For example, the higher-order component `withFoo()`, when passed a component `Bar` should produce a component with a `displayName` of `withFoo(Bar)`.
+ - **高阶组件`HOC`命名**: 用高阶组件名和传入的组件名组合作为生成的组件的 `displayName`。 举个例子,一个高阶组件 `withFoo()`, 当传入一个组件 `Bar` 应该生成一个新的组件,他的 `displayName` 属性是 `withFoo(Bar)`。
- > Why? A component’s `displayName` may be used by developer tools or in error messages, and having a value that clearly expresses this relationship helps people understand what is happening.
+ > Why? 组件的 `displayName` 可以用于开发者工具或者错误信息中,同时还有一个值可以清晰的表达这种组件关系,这可以帮助人们理解到底发生了什么
```jsx
// bad
@@ -137,9 +141,9 @@ This style guide is mostly based on the standards that are currently prevalent i
}
```
- - **Props Naming**: Avoid using DOM component prop names for different purposes.
+ - **Props 命名**: 避免用 DOM 组件的属性名表达不同的意义
- > Why? People expect props like `style` and `className` to mean one specific thing. Varying this API for a subset of your app makes the code less readable and less maintainable, and may cause bugs.
+ > Why? 人们期望 `style`、 `className` 这种属性代表一个明确的意义。 为应用程序的一个子集改变此API会使代码的可读性降低,维护性降低,并可能导致错误。
```jsx
// bad
@@ -154,7 +158,7 @@ This style guide is mostly based on the standards that are currently prevalent i
## Declaration
- - Do not use `displayName` for naming components. Instead, name the component by reference.
+ - 不要通过 `displayName` 命名组件。最好通过引用命名组件。
```jsx
// bad
@@ -170,7 +174,7 @@ This style guide is mostly based on the standards that are currently prevalent i
## Alignment
- - Follow these alignment styles for JSX syntax. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md)
+ - 对 JSX 语法使用这些对齐风格。 eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md) [`react/jsx-closing-tag-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-tag-location.md)
```jsx
// bad
@@ -183,10 +187,10 @@ This style guide is mostly based on the standards that are currently prevalent i
anotherSuperLongParam="baz"
/>
- // if props fit in one line then keep it on the same line
+ // 如果能放在一行,也可以用单行表示
- // children get indented normally
+ // Foo 里面的标签正常缩进
Why? Regular HTML attributes also typically use double quotes instead of single, so JSX attributes mirror this convention.
+ > Why? 正常的 HTML 属性也通常使用双引号而不是单引号,所以 JSX 属性也使用这个约定。
```jsx
// bad
@@ -236,7 +240,7 @@ This style guide is mostly based on the standards that are currently prevalent i
## Spacing
- - Always include a single space in your self-closing tag. eslint: [`no-multi-spaces`](https://eslint.org/docs/rules/no-multi-spaces), [`react/jsx-tag-spacing`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md)
+ - 在自闭合标签内空一格。 eslint: [`no-multi-spaces`](https://eslint.org/docs/rules/no-multi-spaces), [`react/jsx-tag-spacing`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-tag-spacing.md)
```jsx
// bad
@@ -253,7 +257,7 @@ This style guide is mostly based on the standards that are currently prevalent i
```
- - Do not pad JSX curly braces with spaces. eslint: [`react/jsx-curly-spacing`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md)
+ - JSX 里的大括号不要空格。 eslint: [`react/jsx-curly-spacing`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-curly-spacing.md)
```jsx
// bad
@@ -265,7 +269,7 @@ This style guide is mostly based on the standards that are currently prevalent i
## Props
- - Always use camelCase for prop names.
+ - props 用小驼峰
```jsx
// bad
@@ -281,7 +285,7 @@ This style guide is mostly based on the standards that are currently prevalent i
/>
```
- - Omit the value of the prop when it is explicitly `true`. eslint: [`react/jsx-boolean-value`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md)
+ - 如果 prop 的值是 true 可以忽略这个值,直接写 prop 名就可以。 eslint: [`react/jsx-boolean-value`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-boolean-value.md)
```jsx
// bad
@@ -298,7 +302,7 @@ This style guide is mostly based on the standards that are currently prevalent i
```
- - Always include an `alt` prop on `
` tags. If the image is presentational, `alt` can be an empty string or the `
` must have `role="presentation"`. eslint: [`jsx-a11y/alt-text`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md)
+ - `
` 标签通常会设置 `alt` 属性。如果图片是表现型的, `alt`可以是空字符串或者 `
` 必须有 `role="presentation"` 这个属性。 eslint: [`jsx-a11y/alt-text`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/alt-text.md)
```jsx
// bad
@@ -314,9 +318,9 @@ This style guide is mostly based on the standards that are currently prevalent i
```
- - Do not use words like "image", "photo", or "picture" in `
` `alt` props. eslint: [`jsx-a11y/img-redundant-alt`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md)
+ - 不要在 `
` 的 `alt` 属性里用类似 "image", "photo", "picture" 这些单词。 eslint: [`jsx-a11y/img-redundant-alt`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/img-redundant-alt.md)
- > Why? Screenreaders already announce `img` elements as images, so there is no need to include this information in the alt text.
+ > Why? 因为屏幕阅读器已经将 `img` 发音为图片了,所以这个信息就不需要出现在 alt 文本里了。
```jsx
// bad
@@ -326,22 +330,22 @@ This style guide is mostly based on the standards that are currently prevalent i
```
- - Use only valid, non-abstract [ARIA roles](https://www.w3.org/TR/wai-aria/#usage_intro). eslint: [`jsx-a11y/aria-role`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md)
+ - 只用可用的,不抽象的 [ARIA roles](https://www.w3.org/TR/wai-aria/#usage_intro). eslint: [`jsx-a11y/aria-role`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/aria-role.md)
```jsx
- // bad - not an ARIA role
+ // bad - 不是一个 ARIA role
- // bad - abstract ARIA role
+ // bad - 抽象的 ARIA role
// good
```
- - Do not use `accessKey` on elements. eslint: [`jsx-a11y/no-access-key`](https://github.com/evcohen/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md)
+ - 不要在元素上用 `accessKey`。 eslint: [`jsx-a11y/no-access-key`](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/no-access-key.md)
- > Why? Inconsistencies between keyboard shortcuts and keyboard commands used by people using screenreaders and keyboards complicate accessibility.
+ > Why? 使用屏幕阅读器和键盘的人使用的键盘快捷键和键盘命令之间的不一致使得可访问性变得复杂。
```jsx
// bad
@@ -351,11 +355,9 @@ This style guide is mostly based on the standards that are currently prevalent i
```
- - Avoid using an array index as `key` prop, prefer a stable ID.
+ - 避免用数组下标作为 `key` 属性,推荐用稳定的 ID。 eslint: [`react/no-array-index-key`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-array-index-key.md)
-> Why? Not using a stable ID [is an anti-pattern](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) because it can negatively impact performance and cause issues with component state.
-
-We don’t recommend using indexes for keys if the order of items may change.
+ > Why? 不使用稳定杆的 ID [is an anti-pattern](https://medium.com/@robinpokorny/index-as-a-key-is-an-anti-pattern-e0349aece318) 会对组件性能产生消极影响,并且组件状态容易出现问题。 如果数组元素可能会发生变化,我们不推荐使用下标作为key。
```jsx
// bad
@@ -375,9 +377,9 @@ We don’t recommend using indexes for keys if the order of items may change.
))}
```
- - Always define explicit defaultProps for all non-required props.
+ - 对于所有非必须属性,定义一个明确的默认值。
- > Why? propTypes are a form of documentation, and providing defaultProps means the reader of your code doesn’t have to assume as much. In addition, it can mean that your code can omit certain type checks.
+ > Why? propTypes 是一个文档形式,同时提供默认属性意味着使用者不需要假定那么多值。另外,这也意味着你的代码可以忽略类型检查。
```jsx
// bad
@@ -405,12 +407,12 @@ We don’t recommend using indexes for keys if the order of items may change.
};
```
- - Use spread props sparingly.
- > Why? Otherwise you’re more likely to pass unnecessary props down to components. And for React v15.6.1 and older, you could [pass invalid HTML attributes to the DOM](https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html).
+ - 少用props扩展运算符,既 `{...props}`
+ > Why? 除非你更喜欢把不需要的props属性传入组件。而且对于 v15.6.1 及更早以前的 React, 你只能[给DOM元素传非HTML属性的props](https://reactjs.org/blog/2017/09/08/dom-attributes-in-react-16.html)。
- Exceptions:
+ 例外:
- - HOCs that proxy down props and hoist propTypes
+ - HOC 是代理 props 并且提成了propTypes
```jsx
function HOC(WrappedComponent) {
@@ -427,7 +429,7 @@ We don’t recommend using indexes for keys if the order of items may change.
}
```
- - Spreading objects with known, explicit props. This can be particularly useful when testing React components with Mocha’s beforeEach construct.
+ - 扩展一个已知的,有明确属性的对象也是可以的。这个对用 Mocha 的 beforeEach 函数做单测时尤其有用。
```jsx
export default function Foo {
@@ -440,8 +442,8 @@ We don’t recommend using indexes for keys if the order of items may change.
}
```
- Notes for use:
- Filter out unnecessary props when possible. Also, use [prop-types-exact](https://www.npmjs.com/package/prop-types-exact) to help prevent bugs.
+ 使用说明:
+ 尽可能过滤出不需要的属性。同时用[prop-type-exact](https://www.npmjs.com/package/prop-types-exact)去帮助避免bug。
```jsx
// bad
@@ -459,7 +461,7 @@ We don’t recommend using indexes for keys if the order of items may change.
## Refs
- - Always use ref callbacks. eslint: [`react/no-string-refs`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md)
+ - 推荐用 ref callback 函数。 eslint: [`react/no-string-refs`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-string-refs.md)
```jsx
// bad
@@ -475,7 +477,7 @@ We don’t recommend using indexes for keys if the order of items may change.
## Parentheses
- - Wrap JSX tags in parentheses when they span more than one line. eslint: [`react/jsx-wrap-multilines`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md)
+ - 当 JSX 标签有多行时,用圆括号包起来。 eslint: [`react/jsx-wrap-multilines`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-wrap-multilines.md)
```jsx
// bad
@@ -494,7 +496,7 @@ We don’t recommend using indexes for keys if the order of items may change.
);
}
- // good, when single line
+ // good, 单行可以直接写
render() {
const body = hello
;
return {body};
@@ -503,7 +505,7 @@ We don’t recommend using indexes for keys if the order of items may change.
## Tags
- - Always self-close tags that have no children. eslint: [`react/self-closing-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md)
+ - 当没有子元素时,最好用自闭合标签。 eslint: [`react/self-closing-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/self-closing-comp.md)
```jsx
// bad
@@ -513,7 +515,7 @@ We don’t recommend using indexes for keys if the order of items may change.
```
- - If your component has multi-line properties, close its tag on a new line. eslint: [`react/jsx-closing-bracket-location`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
+ - 如果你的组件有多行属性,用他的闭合标签单独作为结束行。 eslint: [`react/jsx-closing-bracket-location`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-closing-bracket-location.md)
```jsx
// bad
@@ -530,7 +532,7 @@ We don’t recommend using indexes for keys if the order of items may change.
## Methods
- - Use arrow functions to close over local variables.
+ - 用箭头函数关闭局部变量。
```jsx
function ItemList(props) {
@@ -547,9 +549,9 @@ We don’t recommend using indexes for keys if the order of items may change.
}
```
- - Bind event handlers for the render method in the constructor. eslint: [`react/jsx-no-bind`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)
+ - 在构造函数里绑定事件处理函数。 eslint: [`react/jsx-no-bind`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/jsx-no-bind.md)
- > Why? A bind call in the render path creates a brand new function on every single render.
+ > Why? render 函数中的绑定调用在每次 render 的时候都会创建一个新的函数。
```jsx
// bad
@@ -581,8 +583,8 @@ We don’t recommend using indexes for keys if the order of items may change.
}
```
- - Do not use underscore prefix for internal methods of a React component.
- > Why? Underscore prefixes are sometimes used as a convention in other languages to denote privacy. But, unlike those languages, there is no native support for privacy in JavaScript, everything is public. Regardless of your intentions, adding underscore prefixes to your properties does not actually make them private, and any property (underscore-prefixed or not) should be treated as being public. See issues [#1024](https://github.com/airbnb/javascript/issues/1024), and [#490](https://github.com/airbnb/javascript/issues/490) for a more in-depth discussion.
+ - 不要在 React 组件里使用下划线作为内部方法名前缀。
+ > Why? 下划线前缀有时候在其他语言里被用于表示私有。但是 JavaScript 原生并不支持私有,所有东西都是公有的。尽管在你的意图里,对你的属性添加下划线前缀不是真的是他变成私有属性,而且任何属性(不论是不是下划线前缀)都被认为是公有的。详细讨论见问题[#1024](https://github.com/airbnb/javascript/issues/1024),和[#490](https://github.com/airbnb/javascript/issues/490)
```jsx
// bad
@@ -604,7 +606,7 @@ We don’t recommend using indexes for keys if the order of items may change.
}
```
- - Be sure to return a value in your `render` methods. eslint: [`react/require-render-return`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/require-render-return.md)
+ - 确保你的 `render` 函数有返回值。 eslint: [`react/require-render-return`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/require-render-return.md)
```jsx
// bad
@@ -620,9 +622,9 @@ We don’t recommend using indexes for keys if the order of items may change.
## Ordering
- - Ordering for `class extends React.Component`:
+ - `class extends React.Component` 内部属性的顺序:
- 1. optional `static` methods
+ 1. 可选的 `static` 方法
1. `constructor`
1. `getChildContext`
1. `componentWillMount`
@@ -632,12 +634,12 @@ We don’t recommend using indexes for keys if the order of items may change.
1. `componentWillUpdate`
1. `componentDidUpdate`
1. `componentWillUnmount`
- 1. *clickHandlers or eventHandlers* like `onClickSubmit()` or `onChangeDescription()`
- 1. *getter methods for `render`* like `getSelectReason()` or `getFooterContent()`
- 1. *optional render methods* like `renderNavigation()` or `renderProfilePicture()`
+ 1. *clickHandlers or eventHandlers* 如: `onClickSubmit()`、 `onChangeDescription()`
+ 1. *getter methods for `render`* 如: `getSelectReason()`、 `getFooterContent()`
+ 1. *optional render methods* 如: `renderNavigation()`、 `renderProfilePicture()`
1. `render`
- - How to define `propTypes`, `defaultProps`, `contextTypes`, etc...
+ - 如何定义 `propTypes`、 `defaultProps`、 `contextTypes` 等...
```jsx
import React from 'react';
@@ -669,7 +671,7 @@ We don’t recommend using indexes for keys if the order of items may change.
export default Link;
```
- - Ordering for `React.createClass`: eslint: [`react/sort-comp`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/sort-comp.md)
+ - `React.createClass` 内部属性排序: eslint: [`react/sort-comp`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/sort-comp.md)
1. `displayName`
1. `propTypes`
@@ -688,24 +690,24 @@ We don’t recommend using indexes for keys if the order of items may change.
1. `componentWillUpdate`
1. `componentDidUpdate`
1. `componentWillUnmount`
- 1. *clickHandlers or eventHandlers* like `onClickSubmit()` or `onChangeDescription()`
- 1. *getter methods for `render`* like `getSelectReason()` or `getFooterContent()`
- 1. *optional render methods* like `renderNavigation()` or `renderProfilePicture()`
+ 1. *clickHandlers or eventHandlers* 如: `onClickSubmit()`、 `onChangeDescription()`
+ 1. *getter methods for `render`* 如: `getSelectReason()`、 `getFooterContent()`
+ 1. *optional render methods* 如: `renderNavigation()`、 `renderProfilePicture()`
1. `render`
## `isMounted`
- - Do not use `isMounted`. eslint: [`react/no-is-mounted`](https://github.com/yannickcr/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md)
+ - 不要用 `isMounted`。 eslint: [`react/no-is-mounted`](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/docs/rules/no-is-mounted.md)
- > Why? [`isMounted` is an anti-pattern][anti-pattern], is not available when using ES6 classes, and is on its way to being officially deprecated.
+ > Why? [`isMounted` 是反模式][anti-pattern], 这个在 ES6 class 里不允许的,而且即将被官方废弃。
- [anti-pattern]: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html
+ [反模式]: https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html
## Translation
- This JSX/React style guide is also available in other languages:
+ JSX/REACT 风格指南的其他语言翻译版
- -  **Chinese (Simplified)**: [JasonBoy/javascript](https://github.com/JasonBoy/javascript/tree/master/react)
+ -  **Chinese (Simplified)**: [lin-123/javascript](https://github.com/lin-123/javascript/tree/cn/react)
-  **Chinese (Traditional)**: [jigsawye/javascript](https://github.com/jigsawye/javascript/tree/master/react)
-  **Español**: [agrcrobles/javascript](https://github.com/agrcrobles/javascript/tree/master/react)
-  **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide/tree/master/react)
@@ -718,4 +720,4 @@ We don’t recommend using indexes for keys if the order of items may change.
-  **Ukrainian**: [ivanzusko/javascript](https://github.com/ivanzusko/javascript/tree/master/react)
-  **Vietnam**: [uetcodecamp/jsx-style-guide](https://github.com/UETCodeCamp/jsx-style-guide)
-**[⬆ back to top](#table-of-contents)**
+**[⬆ back to top](#目录)**
diff --git a/scripts/page.sh b/scripts/page.sh
new file mode 100644
index 0000000000..69906f182f
--- /dev/null
+++ b/scripts/page.sh
@@ -0,0 +1,16 @@
+mkdir dist
+cp README.md dist
+cp -r css-in-javascript dist
+cp -r react dist
+
+git checkout gh-pages
+mv dist/README.md .
+rm -rf react && mv dist/react .
+rm -rf css-in-javascript && mv dist/css-in-javascript .
+rm -rf dist
+
+git add .
+git commit -m 'deploy page'
+git push
+
+git checkout cn
diff --git a/scripts/script.sh b/scripts/script.sh
new file mode 100644
index 0000000000..53dac0cb64
--- /dev/null
+++ b/scripts/script.sh
@@ -0,0 +1,17 @@
+if [ "update" == "$1" ]; then
+ mv README.md README.cn.md
+ mv react/README.md react/README.cn.md
+
+ git add .
+ git commit -m 'update upstream'
+ git pull upstream master
+elif [ "restore" == "$1" ]; then
+ mv README.md README.upstream.md
+ mv README.cn.md README.md
+ mv react/README.md react/README.upstream.md
+ mv react/README.cn.md react/README.md
+
+ git add .
+ git commit -m 'restore readme'
+ git push
+fi
\ No newline at end of file