diff --git a/index.md b/index.md
index e316eb73..ed40c1fa 100644
--- a/index.md
+++ b/index.md
@@ -7,8 +7,9 @@
[](https://gitter.im/airbnb/javascript?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge)
Other Style Guides
- - [ES5](es5/)
+ - [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)
@@ -40,7 +41,7 @@ Other Style Guides
1. [Events](#events)
1. [jQuery](#jquery)
1. [ECMAScript 5 Compatibility](#ecmascript-5-compatibility)
- 1. [ECMAScript 6 Styles](#ecmascript-6-styles)
+ 1. [ECMAScript 6+ (ES 2015+) Styles](#ecmascript-6-es-2015-styles)
1. [Testing](#testing)
1. [Performance](#performance)
1. [Resources](#resources)
@@ -153,45 +154,8 @@ Other Style Guides
const item = {};
```
-
- - [3.2](#objects--reserved-words) If your code will be executed in browsers in script context, don't use [reserved words](http://es5.github.io/#x7.6.1) as keys. It won't work in IE8. [More info](https://github.com/airbnb/javascript/issues/61). It’s OK to use them in ES6 modules and server-side code. jscs: [`disallowIdentifierNames`](http://jscs.info/rule/disallowIdentifierNames)
-
- ```javascript
- // bad
- const superman = {
- default: { clark: 'kent' },
- private: true,
- };
-
- // good
- const superman = {
- defaults: { clark: 'kent' },
- hidden: true,
- };
- ```
-
-
- - [3.3](#objects--reserved-words-2) Use readable synonyms in place of reserved words. jscs: [`disallowIdentifierNames`](http://jscs.info/rule/disallowIdentifierNames)
-
- ```javascript
- // bad
- const superman = {
- class: 'alien',
- };
-
- // bad
- const superman = {
- klass: 'alien',
- };
-
- // good
- const superman = {
- type: 'alien',
- };
- ```
-
- - [3.4](#es6-computed-properties) Use computed property names when creating objects with dynamic property names.
+ - [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.
@@ -217,7 +181,7 @@ Other Style Guides
```
- - [3.5](#es6-object-shorthand) Use object method shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals)
+ - [3.3](#es6-object-shorthand) Use object method shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals)
```javascript
// bad
@@ -240,7 +204,7 @@ Other Style Guides
```
- - [3.6](#es6-object-concise) Use property value shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals)
+ - [3.4](#es6-object-concise) Use property value shorthand. eslint: [`object-shorthand`](http://eslint.org/docs/rules/object-shorthand.html) jscs: [`requireEnhancedObjectLiterals`](http://jscs.info/rule/requireEnhancedObjectLiterals)
> Why? It is shorter to write and descriptive.
@@ -259,7 +223,7 @@ Other Style Guides
```
- - [3.7](#objects--grouped-shorthand) Group your shorthand properties at the beginning of your object declaration.
+ - [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.
@@ -289,45 +253,65 @@ Other Style Guides
```
- - [3.8](#objects--quoted-props) Only quote properties that are invalid identifiers. eslint: [`quote-props`](http://eslint.org/docs/rules/quote-props.html) jscs: [`disallowQuotedKeysInObjects`](http://jscs.info/rule/disallowQuotedKeysInObjects)
+ - [3.6](#objects--quoted-props) Only quote properties that are invalid identifiers. eslint: [`quote-props`](http://eslint.org/docs/rules/quote-props.html) jscs: [`disallowQuotedKeysInObjects`](http://jscs.info/rule/disallowQuotedKeysInObjects)
- > Why? In general we consider it subjectively easier to read. It improves syntax highlighting, and is also more easily optimized by many JS engines.
+ > Why? In general we consider it subjectively easier to read. It improves syntax highlighting, and is also more easily optimized by many JS engines.
- ```javascript
- // bad
- const bad = {
- 'foo': 3,
- 'bar': 4,
- 'data-blah': 5,
- };
+ ```javascript
+ // bad
+ const bad = {
+ 'foo': 3,
+ 'bar': 4,
+ 'data-blah': 5,
+ };
- // good
- const good = {
- foo: 3,
- bar: 4,
- 'data-blah': 5,
- };
- ```
+ // good
+ const good = {
+ foo: 3,
+ bar: 4,
+ 'data-blah': 5,
+ };
+ ```
- - [3.9](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`.
+ - [3.7](#objects--prototype-builtins) Do not call `Object.prototype` methods directly, such as `hasOwnProperty`, `propertyIsEnumerable`, and `isPrototypeOf`.
- > 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)`).
+ > 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)`).
- ```javascript
- // bad
- console.log(object.hasOwnProperty(key));
+ ```javascript
+ // bad
+ console.log(object.hasOwnProperty(key));
- // good
- console.log(Object.prototype.hasOwnProperty.call(object, key));
+ // good
+ console.log(Object.prototype.hasOwnProperty.call(object, key));
- // best
- const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
- /* or */
- const has = require('has');
- …
- console.log(has.call(object, key));
- ```
+ // best
+ const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
+ /* or */
+ import has from 'has';
+ // ...
+ console.log(has.call(object, key));
+ ```
+
+
+ - [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
+
+ // bad
+ const original = { a: 1, b: 2 };
+ const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }
+
+ // good
+ const original = { a: 1, b: 2 };
+ const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }
+
+ const { a, ...noA } = copy; // noA => { b: 2, c: 3 }
+ ```
**[⬆ back to top](#table-of-contents)**
@@ -366,7 +350,7 @@ Other Style Guides
const itemsCopy = [];
let i;
- for (i = 0; i < len; i++) {
+ for (i = 0; i < len; i += 1) {
itemsCopy[i] = items[i];
}
@@ -512,34 +496,36 @@ Other Style Guides
// bad
const name = "Capt. Janeway";
+ // bad - template literals should contain interpolation or newlines
+ 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 be written across multiple lines using string concatenation.
+ - [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.3](#strings--concat-perf) Note: If overused, long strings with concatenation could impact performance. [jsPerf](http://jsperf.com/ya-string-concat) & [Discussion](https://github.com/airbnb/javascript/issues/40).
+ > 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 fast.';
-
// bad
const errorMessage = 'This is a super long error that was thrown because \
of Batman. When you stop to think about how Batman had anything to do \
with this, you would get nowhere \
fast.';
- // good
+ // bad
const errorMessage = 'This is a super long error that was thrown because ' +
'of Batman. When you stop to think about how Batman had anything to do ' +
'with this, you would get nowhere fast.';
+
+ // good
+ const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
```
- - [6.4](#es6-template-literals) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings)
+ - [6.3](#es6-template-literals) When programmatically building up strings, use template strings instead of concatenation. eslint: [`prefer-template`](http://eslint.org/docs/rules/prefer-template.html) [`template-curly-spacing`](http://eslint.org/docs/rules/template-curly-spacing) jscs: [`requireTemplateStrings`](http://jscs.info/rule/requireTemplateStrings)
> Why? Template strings give you a readable, concise syntax with proper newlines and string interpolation features.
@@ -566,10 +552,10 @@ Other Style Guides
```
- - [6.5](#strings--eval) Never use `eval()` on a string, it opens too many vulnerabilities.
+ - [6.4](#strings--eval) Never use `eval()` on a string, it opens too many vulnerabilities.
- - [6.6](#strings--escaping) Do not unnecessarily escape characters in strings. eslint: [`no-useless-escape`](http://eslint.org/docs/rules/no-useless-escape)
+ - [6.5](#strings--escaping) Do not unnecessarily escape characters in strings. eslint: [`no-useless-escape`](http://eslint.org/docs/rules/no-useless-escape)
> Why? Backslashes harm readability, thus they should only be present when necessary.
@@ -579,7 +565,7 @@ Other Style Guides
// good
const foo = '\'this\' is "quoted"';
- const foo = `'this' is "quoted"`;
+ const foo = `my name is '${name}'`;
```
**[⬆ back to top](#table-of-contents)**
@@ -588,18 +574,25 @@ Other Style Guides
## Functions
- - [7.1](#functions--declarations) Use function declarations instead of function expressions. jscs: [`requireFunctionDeclarations`](http://jscs.info/rule/requireFunctionDeclarations)
+ - [7.1](#functions--declarations) Use named function expressions instead of function declarations. eslint: [`func-style`](http://eslint.org/docs/rules/func-style) jscs: [`disallowFunctionDeclarations`](http://jscs.info/rule/disallowFunctionDeclarations)
- > Why? Function declarations are named, so they're easier to identify in call stacks. Also, the whole body of a function declaration is hoisted, whereas only the reference of a function expression is hoisted. This rule makes it possible to always use [Arrow Functions](#arrow-functions) in place of function expressions.
+ > 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 name the expression - anonymous functions can make it harder to locate the problem in an Error's call stack. ([Discussion](https://github.com/airbnb/javascript/issues/794))
```javascript
// bad
const foo = function () {
+ // ...
};
- // good
+ // bad
function foo() {
+ // ...
}
+
+ // good
+ const foo = function bar() {
+ // ...
+ };
```
@@ -642,13 +635,13 @@ Other Style Guides
```javascript
// bad
- function nope(name, options, arguments) {
- // ...stuff...
+ function foo(name, options, arguments) {
+ // ...
}
// good
- function yup(name, options, args) {
- // ...stuff...
+ function foo(name, options, args) {
+ // ...
}
```
@@ -730,7 +723,7 @@ Other Style Guides
```
- - [7.10](#functions--constructor) Never use the Function constructor to create a new function.
+ - [7.10](#functions--constructor) Never use the Function constructor to create a new function. 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.
@@ -743,7 +736,7 @@ Other Style Guides
```
- - [7.11](#functions--signature-spacing) Spacing in a function signature.
+ - [7.11](#functions--signature-spacing) Spacing in a function signature. 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.
@@ -767,12 +760,12 @@ Other Style Guides
// bad
function f1(obj) {
obj.key = 1;
- };
+ }
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
- };
+ }
```
@@ -784,21 +777,79 @@ Other Style Guides
// bad
function f1(a) {
a = 1;
+ // ...
}
function f2(a) {
if (!a) { a = 1; }
+ // ...
}
// good
function f3(a) {
const b = a || 1;
+ // ...
}
function f4(a = 1) {
+ // ...
}
```
+
+ - [7.14](#functions--spread-vs-apply) Prefer the use of the spread operator `...` to call variadic functions. 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`.
+
+ ```javascript
+ // bad
+ const x = [1, 2, 3, 4, 5];
+ console.log.apply(console, x);
+
+ // good
+ const x = [1, 2, 3, 4, 5];
+ console.log(...x);
+
+ // bad
+ new (Function.prototype.bind.apply(Date, [null, 2016, 8, 5]));
+
+ // good
+ 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.
+
+ ```javascript
+ // bad
+ function foo(bar,
+ baz,
+ quux) {
+ // ...
+ }
+
+ // good
+ function foo(
+ bar,
+ baz,
+ quux,
+ ) {
+ // ...
+ }
+
+ // bad
+ console.log(foo,
+ bar,
+ baz);
+
+ // good
+ console.log(
+ foo,
+ bar,
+ baz,
+ );
+ ```
+
**[⬆ back to top](#table-of-contents)**
## Arrow Functions
@@ -847,7 +898,7 @@ Other Style Guides
// good
[1, 2, 3].map((number, index) => ({
- index: number
+ [index]: number,
}));
```
@@ -856,17 +907,20 @@ Other Style Guides
> Why? It shows clearly where the function starts and ends.
- ```js
+ ```javascript
// bad
- [1, 2, 3].map(number => 'As time went by, the string containing the ' +
- `${number} became much longer. So we needed to break it over multiple ` +
- 'lines.'
+ ['get', 'post', 'put'].map(httpMethod => Object.prototype.hasOwnProperty.call(
+ httpMagicObjectWithAVeryLongName,
+ httpMethod,
+ )
);
// good
- [1, 2, 3].map(number => (
- `As time went by, the string containing the ${number} became much ` +
- 'longer. So we needed to break it over multiple lines.'
+ ['get', 'post', 'put'].map(httpMethod => (
+ Object.prototype.hasOwnProperty.call(
+ httpMagicObjectWithAVeryLongName,
+ httpMethod,
+ )
));
```
@@ -875,7 +929,7 @@ Other Style Guides
> Why? Less visual clutter.
- ```js
+ ```javascript
// bad
[1, 2, 3].map((x) => x * x);
@@ -884,8 +938,7 @@ Other Style Guides
// good
[1, 2, 3].map(number => (
- `A long string with the ${number}. It’s so long that we’ve broken it ` +
- 'over multiple lines!'
+ `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
@@ -904,7 +957,7 @@ Other Style Guides
- [8.5](#arrows--confusing) Avoid confusing arrow function syntax (`=>`) with comparison operators (`<=`, `>=`). eslint: [`no-confusing-arrow`](http://eslint.org/docs/rules/no-confusing-arrow)
- ```js
+ ```javascript
// bad
const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
@@ -912,7 +965,13 @@ Other Style Guides
const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
// good
- const itemHeight = (item) => { return 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;
+ };
```
**[⬆ back to top](#table-of-contents)**
@@ -963,13 +1022,13 @@ Other Style Guides
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function () {
- return this._queue[0];
- }
+ return this.queue[0];
+ };
// good
class PeekableQueue extends Queue {
peek() {
- return this._queue[0];
+ return this.queue[0];
}
}
```
@@ -1129,7 +1188,7 @@ Other Style Guides
```javascript
// bad
// filename es6.js
- export { es6 as default } from './airbnbStyleGuide';
+ export { es6 as default } from './AirbnbStyleGuide';
// good
// filename es6.js
@@ -1166,11 +1225,11 @@ Other Style Guides
```javascript
// bad
let foo = 3;
- export { foo }
+ export { foo };
// good
const foo = 3;
- export { foo }
+ export { foo };
```
@@ -1187,7 +1246,7 @@ Other Style Guides
- [10.7](#modules--imports-first) Put all `import`s above non-import statements.
- eslint: [`import/imports-first`](https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md)
+ 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.
```javascript
@@ -1204,15 +1263,51 @@ Other Style Guides
foo.init();
```
+
+ - [10.8](#modules--multiline-imports-over-newlines) Multiline imports should be indented just like multiline array and object literals.
+
+ > 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
+ import {longNameA, longNameB, longNameC, longNameD, longNameE} from 'path';
+
+ // good
+ import {
+ longNameA,
+ longNameB,
+ longNameC,
+ longNameD,
+ longNameE,
+ } 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`.
+
+ ```javascript
+ // bad
+ import fooSass from 'css!sass!foo.scss';
+ import barCss from 'style!css!bar.css';
+
+ // good
+ import fooSass from 'foo.scss';
+ import barCss from 'bar.css';
+ ```
+
**[⬆ back to top](#table-of-contents)**
## Iterators and Generators
- - [11.1](#iterators--nope) Don't use iterators. Prefer JavaScript's higher-order functions like `map()` and `reduce()` instead of loops like `for-of`. eslint: [`no-iterator`](http://eslint.org/docs/rules/no-iterator.html)
+ - [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`](http://eslint.org/docs/rules/no-iterator.html) [`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.
+
```javascript
const numbers = [1, 2, 3, 4, 5];
@@ -1221,7 +1316,6 @@ Other Style Guides
for (let num of numbers) {
sum += num;
}
-
sum === 15;
// good
@@ -1232,6 +1326,19 @@ Other Style Guides
// best (use the functional force)
const sum = numbers.reduce((total, num) => total + num, 0);
sum === 15;
+
+ // bad
+ const increasedByOne = [];
+ for (let i = 0; i < numbers.length; i++) {
+ increasedByOne.push(numbers[i] + 1);
+ }
+
+ // good
+ const increasedByOne = [];
+ numbers.forEach(num => increasedByOne.push(num + 1));
+
+ // best (keeping it functional)
+ const increasedByOne = numbers.map(num => num + 1);
```
@@ -1244,43 +1351,60 @@ Other Style Guides
> Why? `function` and `*` are part of the same conceptual keyword - `*` is not a modifier for `function`, `function*` is a unique construct, different from `function`.
- ```js
+ ```javascript
// bad
function * foo() {
+ // ...
}
+ // bad
const bar = function * () {
- }
+ // ...
+ };
+ // bad
const baz = function *() {
- }
+ // ...
+ };
+ // bad
const quux = function*() {
- }
+ // ...
+ };
+ // bad
function*foo() {
+ // ...
}
+ // bad
function *foo() {
+ // ...
}
// very bad
function
*
foo() {
+ // ...
}
+ // very bad
const wat = function
*
() {
- }
+ // ...
+ };
// good
function* foo() {
+ // ...
}
+ // good
const foo = function* () {
- }
+ // ...
+ };
```
**[⬆ back to top](#table-of-contents)**
@@ -1326,7 +1450,7 @@ Other Style Guides
## Variables
- - [13.1](#variables--const) Always use `const` 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.
+ - [13.1](#variables--const) Always use `const` 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`](http://eslint.org/docs/rules/no-undef) [`prefer-const`](http://eslint.org/docs/rules/prefer-const)
```javascript
// bad
@@ -1423,6 +1547,72 @@ Other Style Guides
return name;
}
```
+
+ - [13.5](#variables--no-chain-assignment) Don't chain variable assignments.
+
+ > Why? Chaining variable assignments creates implicit global variables.
+
+ ```javascript
+ // bad
+ (function example() {
+ // JavaScript interprets this as
+ // let a = ( b = ( c = 1 ) );
+ // The let keyword only applies to variable a; variables b and c become
+ // global variables.
+ let a = b = c = 1;
+ }());
+
+ console.log(a); // undefined
+ console.log(b); // 1
+ console.log(c); // 1
+
+ // good
+ (function example() {
+ let a = 1;
+ let b = a;
+ let c = a;
+ }());
+
+ console.log(a); // undefined
+ console.log(b); // undefined
+ console.log(c); // undefined
+
+ // the same applies for `const`
+ ```
+
+
+ - [13.6](#variables--unary-increment-decrement) Avoid using unary increments and decrements (++, --). eslint [`no-plusplus`](http://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.
+
+ ```javascript
+ // bad
+
+ let 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++;
+ }
+ }
+
+ // good
+
+ let 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;
+ ```
**[⬆ back to top](#table-of-contents)**
@@ -1505,7 +1695,7 @@ Other Style Guides
var named = function named() {
console.log('named');
- }
+ };
}
```
@@ -1550,39 +1740,49 @@ Other Style Guides
```
- - [15.3](#comparison--shortcuts) Use shortcuts.
+ - [15.3](#comparison--shortcuts) Use shortcuts for booleans, but explicit comparisons for strings and numbers.
```javascript
// bad
- if (name !== '') {
- // ...stuff...
+ if (isValid === true) {
+ // ...
}
// good
- if (name) {
- // ...stuff...
+ if (isValid) {
+ // ...
}
// bad
- if (collection.length > 0) {
- // ...stuff...
+ if (name) {
+ // ...
}
// good
+ if (name !== '') {
+ // ...
+ }
+
+ // bad
if (collection.length) {
- // ...stuff...
+ // ...
+ }
+
+ // good
+ if (collection.length > 0) {
+ // ...
}
```
- - [15.4](#comparison--moreinfo) For more information see [Truth Equality and JavaScript](http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/#more-2108) by Angus Croll.
+ - [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.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`).
- > 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.
+ > 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.
- eslint rules: [`no-case-declarations`](http://eslint.org/docs/rules/no-case-declarations.html).
+ eslint rules: [`no-case-declarations`](http://eslint.org/docs/rules/no-case-declarations.html).
```javascript
// bad
@@ -1594,7 +1794,9 @@ Other Style Guides
const y = 2;
break;
case 3:
- function f() {}
+ function f() {
+ // ...
+ }
break;
default:
class C {}
@@ -1611,7 +1813,9 @@ Other Style Guides
break;
}
case 3: {
- function f() {}
+ function f() {
+ // ...
+ }
break;
}
case 4:
@@ -1723,7 +1927,7 @@ Other Style Guides
## Comments
- - [17.1](#comments--multiline) Use `/** ... */` for multi-line comments. Include a description, specify types and values for all parameters and return values.
+ - [17.1](#comments--multiline) Use `/** ... */` for multi-line comments.
```javascript
// bad
@@ -1734,7 +1938,7 @@ Other Style Guides
// @return {Element} element
function make(tag) {
- // ...stuff...
+ // ...
return element;
}
@@ -1742,14 +1946,11 @@ Other Style Guides
// good
/**
* make() returns a new element
- * based on the passed in tag name
- *
- * @param {String} tag
- * @return {Element} element
+ * based on the passed-in tag name
*/
function make(tag) {
- // ...stuff...
+ // ...
return element;
}
@@ -1770,7 +1971,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;
}
@@ -1780,7 +1981,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;
}
@@ -1788,17 +1989,53 @@ 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;
}
```
+ - [17.3](#comments--spaces) Start all comments with a space to make it easier to read. eslint: [`spaced-comment`](http://eslint.org/docs/rules/spaced-comment)
+
+ ```javascript
+ // bad
+ //is current tab
+ const active = true;
+
+ // good
+ // is current tab
+ const active = true;
+
+ // bad
+ /**
+ *make() returns a new element
+ *based on the passed-in tag name
+ */
+ function make(tag) {
+
+ // ...
+
+ return element;
+ }
+
+ // good
+ /**
+ * make() returns a new element
+ * based on the passed-in tag name
+ */
+ function make(tag) {
+
+ // ...
+
+ return element;
+ }
+ ```
+
- - [17.3](#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`.
+ - [17.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`.
- - [17.4](#comments--fixme) Use `// FIXME:` to annotate problems.
+ - [17.5](#comments--fixme) Use `// FIXME:` to annotate problems.
```javascript
class Calculator extends Abacus {
@@ -1812,7 +2049,7 @@ Other Style Guides
```
- - [17.5](#comments--todo) Use `// TODO:` to annotate solutions to problems.
+ - [17.6](#comments--todo) Use `// TODO:` to annotate solutions to problems.
```javascript
class Calculator extends Abacus {
@@ -1836,17 +2073,17 @@ Other Style Guides
```javascript
// bad
function foo() {
- ∙∙∙∙const name;
+ ∙∙∙∙let name;
}
// bad
function bar() {
- ∙const name;
+ ∙let name;
}
// good
function baz() {
- ∙∙const name;
+ ∙∙let name;
}
```
@@ -1914,28 +2151,28 @@ Other Style Guides
```
- - [18.5](#whitespace--newline-at-end) End files with a single newline character.
+ - [18.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)
```javascript
// bad
- (function (global) {
- // ...stuff...
- })(this);
+ import { es6 } from './AirbnbStyleGuide';
+ // ...
+ export default es6;
```
```javascript
// bad
- (function (global) {
- // ...stuff...
- })(this);↵
+ import { es6 } from './AirbnbStyleGuide';
+ // ...
+ export default es6;↵
↵
```
```javascript
// good
- (function (global) {
- // ...stuff...
- })(this);↵
+ import { es6 } from './AirbnbStyleGuide';
+ // ...
+ export default es6;↵
```
@@ -1965,7 +2202,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
@@ -1975,7 +2212,7 @@ 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
@@ -2123,20 +2360,24 @@ Other Style Guides
```
- - [18.12](#whitespace--max-len) Avoid having lines of code that are longer than 100 characters (including whitespace). eslint: [`max-len`](http://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength)
+ - [18.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`](http://eslint.org/docs/rules/max-len.html) jscs: [`maximumLineLength`](http://jscs.info/rule/maximumLineLength)
> Why? This ensures readability and maintainability.
```javascript
// bad
- const foo = 'Whatever national crop flips the window. The cartoon reverts within the screw. Whatever wizard constrains a helpful ally. The counterpart ascends!';
+ const foo = jsonData && jsonData.foo && jsonData.foo.bar && jsonData.foo.bar.baz && jsonData.foo.bar.baz.quux && jsonData.foo.bar.baz.quux.xyzzy;
// bad
$.ajax({ method: 'POST', url: 'https://airbnb.com/', data: { name: 'John' } }).done(() => console.log('Congratulations!')).fail(() => console.log('You have failed this city.'));
// good
- const foo = 'Whatever national crop flips the window. The cartoon reverts within the screw. ' +
- 'Whatever wizard constrains a helpful ally. The counterpart ascends!';
+ const foo = jsonData
+ && jsonData.foo
+ && jsonData.foo.bar
+ && jsonData.foo.bar.baz
+ && jsonData.foo.bar.baz.quux
+ && jsonData.foo.bar.baz.quux.xyzzy;
// good
$.ajax({
@@ -2190,15 +2431,15 @@ Other Style Guides
- [19.2](#commas--dangling) Additional trailing comma: **Yup.** eslint: [`comma-dangle`](http://eslint.org/docs/rules/comma-dangle.html) jscs: [`requireTrailingComma`](http://jscs.info/rule/requireTrailingComma)
- > 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](es5/README.md#commas) in legacy browsers.
+ > 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.
- ```javascript
+ ```diff
// bad - git diff without trailing comma
const hero = {
firstName: 'Florence',
- lastName: 'Nightingale'
+ lastName: 'Nightingale',
- + inventorOf: ['coxcomb graph', 'modern nursing']
+ + inventorOf: ['coxcomb chart', 'modern nursing']
};
// good - git diff with trailing comma
@@ -2207,7 +2448,9 @@ Other Style Guides
lastName: 'Nightingale',
+ inventorOf: ['coxcomb chart', 'modern nursing'],
};
+ ```
+ ```javascript
// bad
const hero = {
firstName: 'Dana',
@@ -2229,6 +2472,56 @@ Other Style Guides
'Batman',
'Superman',
];
+
+ // bad
+ function createHero(
+ firstName,
+ lastName,
+ inventorOf
+ ) {
+ // does nothing
+ }
+
+ // good
+ function createHero(
+ firstName,
+ lastName,
+ inventorOf,
+ ) {
+ // does nothing
+ }
+
+ // good (note that a comma must not appear after a "rest" element)
+ function createHero(
+ firstName,
+ lastName,
+ inventorOf,
+ ...heroArgs
+ ) {
+ // does nothing
+ }
+
+ // bad
+ createHero(
+ firstName,
+ lastName,
+ inventorOf
+ );
+
+ // good
+ createHero(
+ firstName,
+ lastName,
+ inventorOf,
+ );
+
+ // good (note that a comma must not appear after a "rest" element)
+ createHero(
+ firstName,
+ lastName,
+ inventorOf,
+ ...heroArgs
+ );
```
**[⬆ back to top](#table-of-contents)**
@@ -2253,13 +2546,13 @@ Other Style Guides
}());
// good, but legacy (guards against the function becoming an argument when two files with IIFEs are concatenated)
- ;(() => {
+ ;((() => {
const name = 'Skywalker';
return name;
- }());
+ })());
```
- [Read more](http://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214%237365214).
+ [Read more](https://stackoverflow.com/questions/7365172/semicolon-before-self-invoking-function/7365214%237365214).
**[⬆ back to top](#table-of-contents)**
@@ -2311,7 +2604,7 @@ Other Style Guides
```
- - [21.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](http://jsperf.com/coercion-vs-casting/3), leave a comment explaining why and what you're doing.
+ - [21.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.
```javascript
// good
@@ -2324,12 +2617,12 @@ Other Style Guides
```
- - [21.5](#coercion--bitwise) **Note:** Be careful when using bitshift operations. Numbers are represented as [64-bit values](http://es5.github.io/#x4.3.19), but bitshift operations always return a 32-bit integer ([source](http://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:
+ - [21.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:
```javascript
- 2147483647 >> 0 //=> 2147483647
- 2147483648 >> 0 //=> -2147483648
- 2147483649 >> 0 //=> -2147483647
+ 2147483647 >> 0; // => 2147483647
+ 2147483648 >> 0; // => -2147483648
+ 2147483649 >> 0; // => -2147483647
```
@@ -2354,17 +2647,17 @@ Other Style Guides
## Naming Conventions
- - [22.1](#naming--descriptive) Avoid single letter names. Be descriptive with your naming.
+ - [22.1](#naming--descriptive) Avoid single letter names. Be descriptive with your naming. eslint: [`id-length`](http://eslint.org/docs/rules/id-length)
```javascript
// bad
function q() {
- // ...stuff...
+ // ...
}
// good
function query() {
- // ..stuff..
+ // ...
}
```
@@ -2423,7 +2716,7 @@ Other Style Guides
```
- - [22.5](#naming--self-this) Don't save references to `this`. Use arrow functions or Function#bind. jscs: [`disallowNodeTypes`](http://jscs.info/rule/disallowNodeTypes)
+ - [22.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). jscs: [`disallowNodeTypes`](http://jscs.info/rule/disallowNodeTypes)
```javascript
// bad
@@ -2491,6 +2784,7 @@ Other Style Guides
```javascript
function makeStyleGuide() {
+ // ...
}
export default makeStyleGuide;
@@ -2502,12 +2796,42 @@ Other Style Guides
```javascript
const AirbnbStyleGuide = {
es6: {
- }
+ },
};
export default AirbnbStyleGuide;
```
+
+ - [22.9](#naming--Acronyms-and-Initialisms) Acronyms and initialisms should always be all capitalized, or all lowercased.
+
+ > Why? Names are for readability, not to appease a computer algorithm.
+
+ ```javascript
+ // bad
+ import SmsContainer from './containers/SmsContainer';
+
+ // bad
+ const HttpRequests = [
+ // ...
+ ];
+
+ // good
+ import SMSContainer from './containers/SMSContainer';
+
+ // good
+ const HTTPRequests = [
+ // ...
+ ];
+
+ // best
+ import TextMessageContainer from './containers/TextMessageContainer';
+
+ // best
+ const Requests = [
+ // ...
+ ];
+ ```
**[⬆ back to top](#table-of-contents)**
@@ -2591,7 +2915,7 @@ Other Style Guides
// bad
$(this).trigger('listingUpdated', listing.id);
- ...
+ // ...
$(this).on('listingUpdated', (e, listingId) => {
// do something with listingId
@@ -2604,7 +2928,7 @@ Other Style Guides
// good
$(this).trigger('listingUpdated', { listingId: listing.id });
- ...
+ // ...
$(this).on('listingUpdated', (e, data) => {
// do something with data.listingId
@@ -2638,10 +2962,10 @@ Other Style Guides
function setSidebar() {
$('.sidebar').hide();
- // ...stuff...
+ // ...
$('.sidebar').css({
- 'background-color': 'pink'
+ 'background-color': 'pink',
});
}
@@ -2650,10 +2974,10 @@ Other Style Guides
const $sidebar = $('.sidebar');
$sidebar.hide();
- // ...stuff...
+ // ...
$sidebar.css({
- 'background-color': 'pink'
+ 'background-color': 'pink',
});
}
```
@@ -2687,17 +3011,18 @@ Other Style Guides
## ECMAScript 5 Compatibility
- - [26.1](#es5-compat--kangax) Refer to [Kangax](https://twitter.com/kangax/)'s ES5 [compatibility table](http://kangax.github.io/es5-compat-table/).
+ - [26.1](#es5-compat--kangax) Refer to [Kangax](https://twitter.com/kangax/)'s ES5 [compatibility table](https://kangax.github.io/es5-compat-table/).
**[⬆ back to top](#table-of-contents)**
-## ECMAScript 6 Styles
+
+## ECMAScript 6+ (ES 2015+) Styles
- [27.1](#es6-styles) This is a collection of links to the various ES6 features.
1. [Arrow Functions](#arrow-functions)
-1. [Classes](#constructors)
+1. [Classes](#classes--constructors)
1. [Object Shorthand](#es6-object-shorthand)
1. [Object Concise](#es6-object-concise)
1. [Object Computed Properties](#es6-computed-properties)
@@ -2710,6 +3035,11 @@ Other Style Guides
1. [Iterators and Generators](#iterators-and-generators)
1. [Modules](#modules)
+
+ - [27.2](#tc39-proposals) Do not use [TC39 proposals](https://github.com/tc39/proposals) that have not reached 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.
+
**[⬆ back to top](#table-of-contents)**
## Testing
@@ -2737,13 +3067,13 @@ Other Style Guides
## Performance
- - [On Layout & Web Performance](http://www.kellegous.com/j/2013/01/26/layout-performance/)
- - [String vs Array Concat](http://jsperf.com/string-vs-array-concat/2)
- - [Try/Catch Cost In a Loop](http://jsperf.com/try-catch-in-loop-cost)
- - [Bang Function](http://jsperf.com/bang-function)
- - [jQuery Find vs Context, Selector](http://jsperf.com/jquery-find-vs-context-sel/13)
- - [innerHTML vs textContent for script text](http://jsperf.com/innerhtml-vs-textcontent-for-script-text)
- - [Long String Concatenation](http://jsperf.com/ya-string-concat)
+ - [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)
- Loading...
@@ -2773,19 +3103,19 @@ Other Style Guides
**Other Style Guides**
- [Google JavaScript Style Guide](https://google.github.io/styleguide/javascriptguide.xml)
- - [jQuery Core Style Guidelines](http://contribute.jquery.org/style-guide/js/)
+ - [jQuery Core Style Guidelines](https://contribute.jquery.org/style-guide/js/)
- [Principles of Writing Consistent, Idiomatic JavaScript](https://github.com/rwaldron/idiomatic.js)
**Other Styles**
- [Naming this in nested functions](https://gist.github.com/cjohansen/4135065) - Christian Johansen
- [Conditional Callbacks](https://github.com/airbnb/javascript/issues/52) - Ross Allen
- - [Popular JavaScript Coding Conventions on Github](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun
+ - [Popular JavaScript Coding Conventions on GitHub](http://sideeffect.kr/popularconvention/#javascript) - JeongHoon Byun
- [Multiple var statements in JavaScript, not superfluous](http://benalman.com/news/2012/05/multiple-var-statements-javascript/) - Ben Alman
**Further Reading**
- - [Understanding JavaScript Closures](http://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/) - Angus Croll
+ - [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
- [ES6 Features](https://github.com/lukehoban/es6features) - Luke Hoban
@@ -2793,15 +3123,15 @@ Other Style Guides
**Books**
- - [JavaScript: The Good Parts](http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742) - Douglas Crockford
- - [JavaScript Patterns](http://www.amazon.com/JavaScript-Patterns-Stoyan-Stefanov/dp/0596806752) - Stoyan Stefanov
- - [Pro JavaScript Design Patterns](http://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](http://www.amazon.com/High-Performance-Web-Sites-Essential/dp/0596529309) - Steve Souders
- - [Maintainable JavaScript](http://www.amazon.com/Maintainable-JavaScript-Nicholas-C-Zakas/dp/1449327680) - Nicholas C. Zakas
- - [JavaScript Web Applications](http://www.amazon.com/JavaScript-Web-Applications-Alex-MacCaw/dp/144930351X) - Alex MacCaw
- - [Pro JavaScript Techniques](http://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig
- - [Smashing Node.js: JavaScript Everywhere](http://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch
- - [Secrets of the JavaScript Ninja](http://www.amazon.com/Secrets-JavaScript-Ninja-John-Resig/dp/193398869X) - John Resig and Bear Bibeault
+ - [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
+ - [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
+ - [Pro JavaScript Techniques](https://www.amazon.com/Pro-JavaScript-Techniques-John-Resig/dp/1590597273) - John Resig
+ - [Smashing Node.js: JavaScript Everywhere](https://www.amazon.com/Smashing-Node-js-JavaScript-Everywhere-Magazine/dp/1119962595) - Guillermo Rauch
+ - [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
@@ -2812,9 +3142,8 @@ Other Style Guides
**Blogs**
- - [DailyJS](http://dailyjs.com/)
- [JavaScript Weekly](http://javascriptweekly.com/)
- - [JavaScript, JavaScript...](http://javascriptweblog.wordpress.com/)
+ - [JavaScript, JavaScript...](https://javascriptweblog.wordpress.com/)
- [Bocoup Weblog](https://bocoup.com/weblog)
- [Adequately Good](http://www.adequatelygood.com/)
- [NCZOnline](https://www.nczonline.net/)
@@ -2826,6 +3155,7 @@ Other Style Guides
**Podcasts**
+ - [JavaScript Air](https://javascriptair.com/)
- [JavaScript Jabber](https://devchat.tv/js-jabber/)
@@ -2835,6 +3165,7 @@ Other Style Guides
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.
+ - **3blades**: [3Blades/javascript](https://github.com/3blades/javascript)
- **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)
@@ -2843,9 +3174,11 @@ Other Style Guides
- **Ascribe**: [ascribe/javascript](https://github.com/ascribe/javascript)
- **Avalara**: [avalara/javascript](https://github.com/avalara/javascript)
- **Avant**: [avantcredit/javascript](https://github.com/avantcredit/javascript)
+ - **BashPros**: [BashPros/javascript](https://github.com/BashPros/javascript)
- **Billabong**: [billabong/javascript](https://github.com/billabong/javascript)
- **Bisk**: [bisk/javascript](https://github.com/Bisk/javascript/)
- **Blendle**: [blendle/javascript](https://github.com/blendle/javascript)
+ - **Bonhomme**: [bonhommeparis/javascript](https://github.com/bonhommeparis/javascript)
- **Brainshark**: [brainshark/javascript](https://github.com/brainshark/javascript)
- **Chartboost**: [ChartBoost/javascript-style-guide](https://github.com/ChartBoost/javascript-style-guide)
- **ComparaOnline**: [comparaonline/javascript](https://github.com/comparaonline/javascript-style-guide)
@@ -2875,6 +3208,8 @@ Other Style Guides
- **JSSolutions**: [JSSolutions/javascript](https://github.com/JSSolutions/javascript)
- **KickorStick**: [kickorstick/javascript](https://github.com/kickorstick/javascript)
- **Kinetica Solutions**: [kinetica/javascript](https://github.com/kinetica/Javascript-style-guide)
+ - **Lonely Planet**: [lonelyplanet/javascript](https://github.com/lonelyplanet/javascript)
+ - **M2GEN**: [M2GEN/javascript](https://github.com/M2GEN/javascript)
- **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)
@@ -2884,6 +3219,7 @@ Other Style Guides
- **National Geographic**: [natgeo/javascript](https://github.com/natgeo/javascript)
- **National Park Service**: [nationalparkservice/javascript](https://github.com/nationalparkservice/javascript)
- **Nimbl3**: [nimbl3/javascript](https://github.com/nimbl3/javascript)
+ - **Nulogy**: [nulogy/javascript](https://github.com/nulogy/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)
@@ -2895,8 +3231,12 @@ Other Style Guides
- **SeekingAlpha**: [seekingalpha/javascript-style-guide](https://github.com/seekingalpha/javascript-style-guide)
- **Shutterfly**: [shutterfly/javascript](https://github.com/shutterfly/javascript)
- **Springload**: [springload/javascript](https://github.com/springload/javascript)
+ - **StratoDem Analytics**: [stratodem/javascript](https://github.com/stratodem/javascript)
+ - **SteelKiwi Development**: [steelkiwi/javascript](https://github.com/steelkiwi/javascript)
- **StudentSphere**: [studentsphere/javascript](https://github.com/studentsphere/guide-javascript)
+ - **SwoopApp**: [swoopapp/javascript](https://github.com/swoopapp/javascript)
- **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)
- **TheLadders**: [TheLadders/javascript](https://github.com/TheLadders/javascript)
- **The Nerdery**: [thenerdery/javascript-standards](https://github.com/thenerdery/javascript-standards)
@@ -2921,13 +3261,13 @@ Other Style Guides
-  **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide)
-  **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide)
-  **Italian**: [sinkswim/javascript-style-guide](https://github.com/sinkswim/javascript-style-guide)
- -  **Japanese**: [mitsuruog/javacript-style-guide](https://github.com/mitsuruog/javacript-style-guide)
+ -  **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide)
-  **Korean**: [tipjs/javascript-style-guide](https://github.com/tipjs/javascript-style-guide)
-  **Polish**: [mjurczyk/javascript](https://github.com/mjurczyk/javascript)
- -  **Russian**: [uprock/javascript](https://github.com/uprock/javascript)
+ -  **Russian**: [leonidlebedev/javascript-airbnb](https://github.com/leonidlebedev/javascript-airbnb)
-  **Spanish**: [paolocarrasco/javascript-style-guide](https://github.com/paolocarrasco/javascript-style-guide)
-  **Thai**: [lvarayut/javascript-style-guide](https://github.com/lvarayut/javascript-style-guide)
- -  **Vietnam**: [giangpii/javascript-style-guide](https://github.com/giangpii/javascript-style-guide)
+ -  **Vietnam**: [hngiang/javascript-style-guide](https://github.com/hngiang/javascript-style-guide)
## The JavaScript Style Guide Guide
@@ -2946,7 +3286,7 @@ Other Style Guides
(The MIT License)
-Copyright (c) 2014-2016 Airbnb
+Copyright (c) 2014-2017 Airbnb
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the