diff --git a/index.md b/index.md index e316eb73..ed40c1fa 100644 --- a/index.md +++ b/index.md @@ -7,8 +7,9 @@ [![Gitter](https://badges.gitter.im/Join Chat.svg)](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 - ![fr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/France.png) **French**: [nmussy/javascript-style-guide](https://github.com/nmussy/javascript-style-guide) - ![de](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Germany.png) **German**: [timofurrer/javascript-style-guide](https://github.com/timofurrer/javascript-style-guide) - ![it](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Italy.png) **Italian**: [sinkswim/javascript-style-guide](https://github.com/sinkswim/javascript-style-guide) - - ![jp](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Japan.png) **Japanese**: [mitsuruog/javacript-style-guide](https://github.com/mitsuruog/javacript-style-guide) + - ![jp](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Japan.png) **Japanese**: [mitsuruog/javascript-style-guide](https://github.com/mitsuruog/javascript-style-guide) - ![kr](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/South-Korea.png) **Korean**: [tipjs/javascript-style-guide](https://github.com/tipjs/javascript-style-guide) - ![pl](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Poland.png) **Polish**: [mjurczyk/javascript](https://github.com/mjurczyk/javascript) - - ![ru](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Russia.png) **Russian**: [uprock/javascript](https://github.com/uprock/javascript) + - ![ru](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Russia.png) **Russian**: [leonidlebedev/javascript-airbnb](https://github.com/leonidlebedev/javascript-airbnb) - ![es](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Spain.png) **Spanish**: [paolocarrasco/javascript-style-guide](https://github.com/paolocarrasco/javascript-style-guide) - ![th](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Thailand.png) **Thai**: [lvarayut/javascript-style-guide](https://github.com/lvarayut/javascript-style-guide) - - ![vn](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Vietnam.png) **Vietnam**: [giangpii/javascript-style-guide](https://github.com/giangpii/javascript-style-guide) + - ![vn](https://raw.githubusercontent.com/gosquared/flags/master/flags/flags/shiny/24/Vietnam.png) **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