Photo by Pankaj Patel on Unsplash
Airbnb JavaScript スタイルガイド()
JavaScript に対する、ほぼ妥当なアプローチ
その他のスタイルガイド
Airbnb JavaScript Style Guide から翻訳されました。
型
- 1.1 プリミティブ: プリミティブには直接アクセスします。
stringnumberbooleannullundefined
const foo = 1;
let bar = foo;
bar = 9;
console.log(foo, bar); // => 1, 9
- 1.2 複合: 複合型には参照でアクセスします。
objectarrayfunction
const foo = [1, 2];
const bar = foo;
bar[0] = 9;
console.log(foo[0], bar[0]); // => 9, 9
参照
- 2.1 全ての参照には
constを使用してください。varの使用は避けてください。eslint:prefer-const,no-const-assign
なぜなら、参照を再割り当てできないようにすることで、バグを減らし、コードを理解しやすくするためです。
// bad
var a = 1;
var b = 2;
// good
const a = 1;
const b = 2;
- 2.2 もし参照を再割り当てする必要がある場合は、
varの代わりにletを使用してください。eslint:no-varjscs:disallowVar
なぜなら、
letはvarのような関数スコープではなく、ブロックスコープだからです。
// bad
var count = 1;
if (true) {
count += 1;
}
// good, use the let.
let count = 1;
if (true) {
count += 1;
}
- 2.3
letとconstはどちらもブロックスコープであることに注意してください。
// const と let は、それらが定義されたブロック内でのみ存在します。
{
let a = 1;
const b = 1;
}
console.log(a); // ReferenceError
console.log(b); // ReferenceError
オブジェクト
- 3.1 オブジェクトを作成するときはリテラル構文を使用してください。eslint rules:
no-new-object.
// bad
const item = new Object();
// good
const item = {};
- 3.2 キーに 予約語 を使用しないでください。IE8 では動作しません。詳細はこちら。ES6 モジュールやサーバーサイドのコードで使用するのは問題ありません。jscs:
disallowIdentifierNames
// bad
const superman = {
default: { clark: 'kent' },
private: true,
};
// good
const superman = {
defaults: { clark: 'kent' },
hidden: true,
};
- 3.3 予約語の代わりに、読みやすい同義語を使用してください。jscs:
disallowIdentifierNames
// bad
const superman = {
class: 'alien',
};
// bad
const superman = {
klass: 'alien',
};
// good
const superman = {
type: 'alien',
};
- 3.4 動的なプロパティ名でオブジェクトを作成する場合は、計算されたプロパティ名(computed property names)を使用してください。
なぜなら、オブジェクトのすべてのプロパティを1か所で定義できるからです。
function getKey(k) {
return `a key named ${k}`;
}
// bad
const obj = {
id: 5,
name: 'San Francisco',
};
obj[getKey('enabled')] = true;
// good
const obj = {
id: 5,
name: 'San Francisco',
[getKey('enabled')]: true,
};
- 3.5 オブジェクトメソッドの短縮表記を使用してください。eslint:
object-shorthandjscs:requireEnhancedObjectLiterals
// bad
const atom = {
value: 1,
addValue: function (value) {
return atom.value + value;
},
};
// good
const atom = {
value: 1,
addValue(value) {
return atom.value + value;
},
};
- 3.6 プロパティ値の短縮表記を使用してください。eslint:
object-shorthandjscs:requireEnhancedObjectLiterals
なぜなら、より短く記述でき、明確だからです。
const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
lukeSkywalker: lukeSkywalker,
};
// good
const obj = {
lukeSkywalker,
};
- 3.7 短縮表記のプロパティは、オブジェクト宣言の先頭にグループ化してください。
なぜなら、どのプロパティが短縮表記を使用しているかが分かりやすくなるからです。
const anakinSkywalker = 'Anakin Skywalker';
const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
episodeOne: 1,
twoJediWalkIntoACantina: 2,
lukeSkywalker,
episodeThree: 3,
mayTheFourth: 4,
anakinSkywalker,
};
// good
const obj = {
lukeSkywalker,
anakinSkywalker,
episodeOne: 1,
twoJediWalkIntoACantina: 2,
episodeThree: 3,
mayTheFourth: 4,
};
- 3.8 無効な識別子であるプロパティのみクォートで囲んでください。eslint:
quote-propsjscs:disallowQuotedKeysInObjects
なぜなら、一般的に主観的に読みやすいと考えられているからです。また、シンタックスハイライトが向上し、多くの JS エンジンで最適化されやすくなります。
// bad
const bad = {
'foo': 3,
'bar': 4,
'data-blah': 5,
};
// good
const good = {
foo: 3,
bar: 4,
'data-blah': 5,
};
配列
- 4.1 配列を作成するときはリテラル構文を使用してください。eslint:
no-array-constructor
// bad
const items = new Array();
// good
const items = [];
- 4.2 配列にアイテムを追加するときは、直接代入するのではなく Array#push を使用してください。
const someStack = [];
// bad
someStack[someStack.length] = 'abracadabra';
// good
someStack.push('abracadabra');
- 4.3 配列をコピーするには、スプレッド演算子
...を使用してください。
// bad
const len = items.length;
const itemsCopy = [];
let i;
for (i = 0; i < len; i++) {
itemsCopy[i] = items[i];
}
// good
const itemsCopy = [...items];
- 4.4 配列のようなオブジェクトを配列に変換するには、Array#from を使用してください。
const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);
- 4.5 配列メソッドのコールバックでは return 文を使用してください。ただし、関数本体が単一の文で構成されている場合(8.2 を参照)は、return を省略しても構いません。eslint:
array-callback-return
// good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
// good
[1, 2, 3].map(x => x + 1);
// bad
const flat = {};
[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
const flatten = memo.concat(item);
flat[index] = memo.concat(item);
});
// good
const flat = {};
[[0, 1], [2, 3], [4, 5]].reduce((memo, item, index) => {
const flatten = memo.concat(item);
flat[index] = flatten;
return flatten;
});
// bad
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird') {
return author === 'Harper Lee';
} else {
return false;
}
});
// good
inbox.filter((msg) => {
const { subject, author } = msg;
if (subject === 'Mockingbird') {
return author === 'Harper Lee';
}
return false;
});
分割代入
- 5.1 オブジェクトの複数のプロパティにアクセスして使用する場合は、オブジェクトの分割代入を使用してください。jscs:
requireObjectDestructuring
なぜなら、プロパティのための一時的な参照を作成せずに済むからです。
// bad
function getFullName(user) {
const firstName = user.firstName;
const lastName = user.lastName;
return `${firstName} ${lastName}`;
}
// good
function getFullName(user) {
const { firstName, lastName } = user;
return `${firstName} ${lastName}`;
}
// best
function getFullName({ firstName, lastName }) {
return `${firstName} ${lastName}`;
}
- 5.2 配列の分割代入を使用してください。jscs:
requireArrayDestructuring
const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
- 5.3 複数の値を返す場合は、配列の分割代入ではなく、オブジェクトの分割代入を使用してください。
なぜなら、呼び出し元を壊すことなく、新しいプロパティを追加したり、順序を変更したりできるからです。
// bad
function processInput(input) {
// then a miracle occurs
return [left, right, top, bottom];
}
// the caller needs to think about the order of return data
const [left, __, top] = processInput(input);
// good
function processInput(input) {
// then a miracle occurs
return { left, right, top, bottom };
}
// the caller selects only the data they need
const { left, right } = processInput(input);
文字列
- 6.1 文字列にはシングルクォート
''を使用してください。eslint:quotesjscs:validateQuoteMarks
// bad
const name = "Capt. Janeway";
// good
const name = 'Capt. Janeway';
- 6.2 1行が100文字を超えるような文字列は、文字列連結を使って複数行に分けて書くべきではありません。
- 6.3 注意: 長い文字列の連結を過度に使用すると、パフォーマンスに影響を与える可能性があります。jsPerf & Discussion.
// bad
const errorMessage = 'This is a super long error that was thrown because of Batman. When you stop to think about how Batman had anything to do with this, you would get nowhere fast.';
// bad
const errorMessage = 'This is a super long error that was thrown because \
of Batman. When you stop to think about how Batman had anything to do \
with this, you would get nowhere \
fast.';
// good
const errorMessage = 'This is a super long error that was thrown because ' +
'of Batman. When you stop to think about how Batman had anything to do ' +
'with this, you would get nowhere fast.';
- 6.4 プログラムで文字列を作成する場合は、連結ではなくテンプレート文字列を使用してください。eslint:
prefer-templatetemplate-curly-spacingjscs:requireTemplateStrings
なぜなら、テンプレート文字列は、適切な改行や文字列補間機能を備えた、読みやすく簡潔な構文を提供するからです。
// bad
function sayHi(name) {
return 'How are you, ' + name + '?';
}
// bad
function sayHi(name) {
return ['How are you, ', name, '?'].join();
}
// bad
function sayHi(name) {
return `How are you, ${ name }?`;
}
// good
function sayHi(name) {
return `How are you, ${name}?`;
}
- 6.5 文字列に対して
eval()を決して使用しないでください。脆弱性が多すぎます。
関数
- 7.1 関数式ではなく関数宣言を使用してください。jscs:
requireFunctionDeclarations
なぜなら、関数宣言には名前が付いているため、スタックトレースで識別しやすくなるからです。また、関数宣言はホイスティング(巻き上げ)されますが、関数式はされません。このルールにより、アロー関数 が関数式を完全に置き換えることができます。
// bad
const foo = function () {
};
// good
function foo() {
}
- 7.2 IIFE (即時実行関数式): eslint:
wrap-iifejscs:requireParenthesesAroundIIFE
なぜなら、IIFE は単一のユニットだからです。関数とその呼び出しの両方を括弧で囲むことで、これが明確になります。モジュールの世界では、通常 IIFE はもう必要ないことに注意してください。
// immediately-invoked function expression (IIFE)
(function () {
console.log('Welcome to the Internet. Please follow me.');
}());
-
7.3 関数以外のブロック(if、while など)の中で関数を宣言しないでください。代わりに関数を変数に割り当ててください。ブラウザでは許可されていますが、それぞれの解釈が異なります。eslint:
no-loop-func -
7.4 注意: ECMA-262 では
blockを文のリストとして定義しています。関数宣言は文ではありません。この問題に関する ECMA-262 の注記を読んでください。
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
let test;
if (currentUser) {
test = () => {
console.log('Yup.');
};
}
- 7.5 パラメータに
argumentsという名前を付けないでください。これは、すべての関数スコープに与えられるargumentsオブジェクトよりも優先されてしまいます。
// bad
function nope(name, options, arguments) {
// ...stuff...
}
// good
function yup(name, options, args) {
// ...stuff...
}
- 7.6
argumentsを使用せず、代わりに rest 構文...を使用してください。prefer-rest-params
なぜなら、
...はどの引数を取り出すかを明示できるからです。さらに、rest 引数はargumentsのような「配列のようなオブジェクト」ではなく、本物の配列です。
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
- 7.7 関数の引数を変更するのではなく、デフォルトパラメータ構文を使用してください。
// really bad
function handleThings(opts) {
// No! We shouldn't mutate function arguments.
// Double bad: if opts is false it will be set to an object which may
// be what you want but it can cause subtle bugs.
opts = opts || {};
// ...
}
// still bad
function handleThings(opts) {
if (opts === void 0) {
opts = {};
}
// ...
}
// good
function handleThings(opts = {}) {
// ...
}
- 7.8 デフォルトパラメータでの副作用は避けてください。
なぜなら、動作を理解するのが混乱するからです。
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
- 7.9 デフォルトパラメータは常に最後に置いてください。
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
- 7.10 新しい関数を作成するために Function コンストラクタを使用しないでください。
なぜなら、この方法で関数を作成すると、eval() と同様に文字列が評価され、脆弱性を引き起こす可能性があるからです。
// bad
var add = new Function('a', 'b', 'return a + b');
// still bad
var subtract = Function('a', 'b', 'return a - b');
- 7.11 関数シグネチャの空白。
なぜなら、一貫性は良いことですし、名前を追加または削除するときにスペースを追加または削除する必要がないからです。
// bad
const f = function(){};
const g = function (){};
const h = function() {};
// good
const x = function () {};
const y = function a() {};
- 7.12 パラメータを決して変更(mutate)しないでください。eslint:
no-param-reassign
なぜなら、パラメータとして渡されたオブジェクトを操作すると、呼び出し元で予期しない変数の副作用が発生する可能性があるからです。
// bad
function f1(obj) {
obj.key = 1;
};
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
};
- 7.13 パラメータに再代入しないでください。eslint:
no-param-reassign
なぜなら、パラメータへの再代入は、特に
argumentsオブジェクトにアクセスする場合に予期しない動作を引き起こす可能性があるからです。また、特に V8 エンジンでは最適化の問題を引き起こす可能性もあります。
```javascript
// 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) {
}
```
アロー関数
- 8.1 関数式を使用する必要がある場合(匿名関数を渡す場合など)は、アロー関数記法を使用してください。eslint:
prefer-arrow-callback,arrow-spacingjscs:requireArrowFunctions
なぜなら、これは
thisのコンテキストで実行されるバージョンの関数を作成し(通常はこれが望ましい動作です)、構文もより簡潔だからです。
なぜダメなのか? かなり複雑な関数の場合は、そのロジックを独自の関数宣言に移動した方がよいかもしれません。
// bad
[1, 2, 3].map(function (x) {
const y = x + 1;
return x * y;
});
// good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
- 8.2 関数本体が副作用のない式を返す単一の文で構成されている場合は、中括弧を省略し、暗黙の return を使用してください。それ以外の場合は、中括弧を保持し、
return文を使用してください。eslint:arrow-parens,arrow-body-stylejscs:disallowParenthesesAroundArrowParam,requireShorthandArrowFunctions
なぜなら、シンタックスシュガーだからです。複数の関数を連鎖させる場合に読みやすくなります。
なぜダメなのか? オブジェクトを返す予定がある場合。
// bad
[1, 2, 3].map(number => {
const nextNumber = number + 1;
`A string containing the ${nextNumber}.`;
});
// good
[1, 2, 3].map(number => `A string containing the ${number}.`);
// good
[1, 2, 3].map((number) => {
const nextNumber = number + 1;
return `A string containing the ${nextNumber}.`;
});
- 8.3 式が複数行にまたがる場合は、読みやすくするために括弧で囲んでください。
なぜなら、関数の開始と終了が明確になるからです。
// 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.'
);
// 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.'
));
- 8.4 関数が単一の引数を取り、中括弧を使用しない場合は、括弧を省略してください。それ以外の場合は、常に引数を括弧で囲んでください。eslint:
arrow-parensjscs:disallowParenthesesAroundArrowParam
なぜなら、見た目がすっきりするからです。
// bad
[1, 2, 3].map((x) => x * x);
// good
[1, 2, 3].map(x => x * x);
```javascript
// good
[1, 2, 3].map(number => (
`A long string with the ${number}. It’s so long that we’ve broken it ` +
'over multiple lines!'
));
// bad
[1, 2, 3].map(x => {
const y = x + 1;
return x * y;
});
// good
[1, 2, 3].map((x) => {
const y = x + 1;
return x * y;
});
- 8.5 アロー関数構文 (
=>) と比較演算子 (<=,>=) を混同しないようにしてください。eslint:no-confusing-arrow
// bad
const itemHeight = item => item.height > 256 ? item.largeSize : item.smallSize;
// bad
const itemHeight = (item) => item.height > 256 ? item.largeSize : item.smallSize;
// good
const itemHeight = item => { return item.height > 256 ? item.largeSize : item.smallSize; }
クラス
- 9.1 常に
classを使用してください。prototypeを直接操作することは避けてください。
なぜなら、
class構文の方が簡潔で、論理的に理解しやすいからです。
// bad
function Queue(contents = []) {
this._queue = [...contents];
}
Queue.prototype.pop = function () {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
// good
class Queue {
constructor(contents = []) {
this._queue = [...contents];
}
pop() {
const value = this._queue[0];
this._queue.splice(0, 1);
return value;
}
}
- 9.2 継承には
extendsを使用してください。
なぜなら、これは
instanceofを破壊することなくプロトタイプから機能を継承する組み込みの方法だからです。
// bad
const inherits = require('inherits');
function PeekableQueue(contents) {
Queue.apply(this, contents);
}
inherits(PeekableQueue, Queue);
PeekableQueue.prototype.peek = function () {
return this._queue[0];
}
// good
class PeekableQueue extends Queue {
peek() {
return this._queue[0];
}
}
- 9.3 メソッドチェーンを助けるために、メソッド内で
thisを返すことができます。
// bad
Jedi.prototype.jump = function () {
this.jumping = true;
return true;
};
Jedi.prototype.setHeight = function (height) {
this.height = height;
};
const luke = new Jedi();
luke.jump(); // => true
luke.setHeight(20); // => undefined
// good
class Jedi {
jump() {
this.jumping = true;
return this;
}
setHeight(height) {
this.height = height;
return this;
}
}
const luke = new Jedi();
luke.jump()
.setHeight(20);
- 9.4 カスタムの toString() メソッドを作成しても構いませんが、正しく動作し、副作用がないことを確認してください。
class Jedi {
constructor(options = {}) {
this.name = options.name || 'no name';
}
getName() {
return this.name;
}
toString() {
return `Jedi - ${this.getName()}`;
}
}
- 9.5 指定されていない場合、クラスにはデフォルトのコンストラクタがあります。空のコンストラクタや、単に親クラスに委譲するだけのコンストラクタは不要です。
no-useless-constructor
// bad
class Jedi {
constructor() {}
getName() {
return this.name;
}
}
// bad
class Rey extends Jedi {
constructor(...args) {
super(...args);
}
}
// good
class Rey extends Jedi {
constructor(...args) {
super(...args);
this.name = 'Rey';
}
}
モジュール
- 10.1 非標準のモジュールシステムよりも、常にモジュール (
import/export) を使用してください。いつでも好みのモジュールシステムにトランスパイルできます。
なぜなら、モジュールは未来の標準であり、今から未来を使い始めるべきだからです。
// bad
const AirbnbStyleGuide = require('./AirbnbStyleGuide');
module.exports = AirbnbStyleGuide.es6;
// ok
import AirbnbStyleGuide from './AirbnbStyleGuide';
export default AirbnbStyleGuide.es6;
// best
import { es6 } from './AirbnbStyleGuide';
export default es6;
- 10.2 ワイルドカードインポートは使用しないでください。
なぜなら、これにより単一のデフォルトエクスポートを持つことが保証されるからです。
// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';
// good
import AirbnbStyleGuide from './AirbnbStyleGuide';
- 10.3 また、インポートから直接エクスポートしないでください。
なぜなら、一行で書けるのは簡潔ですが、インポートとエクスポートを明確に分けることで一貫性が保たれるからです。
// bad
// filename es6.js
export { es6 as default } from './airbnbStyleGuide';
// good
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;
イテレータとジェネレータ
- 11.1 イテレータを使用しないでください。
for-ofループの代わりに、map()やreduce()のような JavaScript の高階関数を使用してください。eslint:no-iterator
なぜなら、これは不変性のルールを強制するためです。副作用を扱うよりも、値を返す純粋関数を扱う方が論理的に理解しやすいからです。
eslint rules: no-iterator.
const numbers = [1, 2, 3, 4, 5];
// bad
let sum = 0;
for (let num of numbers) {
sum += num;
}
sum === 15;
// good
let sum = 0;
numbers.forEach(num => sum += num);
sum === 15;
// best (use the functional force)
const sum = numbers.reduce((total, num) => total + num, 0);
sum === 15;
- 11.2 ジェネレータは今のところ使用しないでください。
なぜなら、まだ ES5 へのトランスパイルが完全ではないからです。
プロパティ
- 12.1 プロパティにアクセスするときはドット記法を使用してください。eslint:
dot-notationjscs:requireDotNotation
const luke = {
jedi: true,
age: 28,
};
// bad
const isJedi = luke['jedi'];
// good
const isJedi = luke.jedi;
- 12.2 変数を使ってプロパティにアクセスするときはブラケット記法
[]を使用してください。
const luke = {
jedi: true,
age: 28,
};
function getProp(prop) {
return luke[prop];
}
const isJedi = getProp('jedi');
変数
- 13.1 変数を宣言するときは常に
constまたはletを使用してください。そうしないとグローバル変数になってしまいます。グローバル名前空間の汚染は避けたいものです。キャプテン・プラネットもそう警告していました。
// bad
superPower = new SuperPower();
// good
const superPower = new SuperPower();
- 13.2 変数ごとに
constまたはlet宣言を1つ使用してください。eslint:one-varjscs:disallowMultipleVarDecl
なぜなら、この方が新しい変数の宣言を追加しやすく、
;を,に置き換えたり、句読点だけの差分が発生したりする心配がないからです。
// bad
const items = getItems(),
goSportsTeam = true,
dragonball = 'z';
// bad
// (compare to above, notice the error)
const items = getItems(),
goSportsTeam = true;
dragonball = 'z';
// good
const items = getItems();
const goSportsTeam = true;
const dragonball = 'z';
- 13.3 すべての
constをグループ化し、次にすべてのletをグループ化してください。
なぜなら、後になって以前に割り当てられた変数に基づいて変数を割り当てる必要がある場合に役立つからです。
// bad
let i, len, dragonball,
items = getItems(),
goSportsTeam = true;
// bad
let i;
const items = getItems();
let dragonball;
const goSportsTeam = true;
let len;
// good
const goSportsTeam = true;
const items = getItems();
let dragonball;
let i;
let length;
- 13.4 変数は必要な場所で割り当てますが、妥当な場所に配置してください。
なぜなら、
letとconstは関数スコープではなくブロックスコープだからです。
// bad - unnecessary function call
function checkName(hasName) {
const name = getName();
if (hasName === 'test') {
return false;
}
if (name === 'test') {
this.setName('');
return false;
}
return name;
}
// good
function checkName(hasName) {
if (hasName === 'test') {
return false;
}
const name = getName();
if (name === 'test') {
this.setName('');
return false;
}
return name;
}
ホイスティング
- 14.1
var宣言はスコープの先頭に巻き上げられますが、その代入は巻き上げられません。constとlet宣言には、Temporal Dead Zones (TDZ) と呼ばれる新しい概念があります。なぜ typeof がもはや安全ではない のかを知ることは重要です。
// we know this wouldn't work (assuming there
// is no notDefined global variable)
function example() {
console.log(notDefined); // => throws a ReferenceError
}
// creating a variable declaration after you
// reference the variable will work due to
// variable hoisting. Note: the assignment
// value of `true` is not hoisted.
function example() {
console.log(declaredButNotAssigned); // => undefined
var declaredButNotAssigned = true;
}
// The interpreter is hoisting the variable
// declaration to the top of the scope,
// which means our example could be rewritten as:
function example() {
let declaredButNotAssigned;
console.log(declaredButNotAssigned); // => undefined
declaredButNotAssigned = true;
}
// using const and let
function example() {
console.log(declaredButNotAssigned); // => throws a ReferenceError
console.log(typeof declaredButNotAssigned); // => throws a ReferenceError
const declaredButNotAssigned = true;
}
- 14.2 匿名関数式は変数名を巻き上げますが、関数の代入は巻き上げません。
function example() {
console.log(anonymous); // => undefined
anonymous(); // => TypeError anonymous is not a function
var anonymous = function () {
console.log('anonymous function expression');
};
}
- 14.3 名前付き関数式は変数名を巻き上げますが、関数名や関数本体は巻き上げません。
function example() {
console.log(named); // => undefined
named(); // => TypeError named is not a function
superPower(); // => ReferenceError superPower is not defined
var named = function superPower() {
console.log('Flying');
};
}
// the same is true when the function name
// is the same as the variable name.
function example() {
console.log(named); // => undefined
named(); // => TypeError named is not a function
var named = function named() {
console.log('named');
}
}
- 14.4 関数宣言は、その名前と関数本体を巻き上げます。
function example() {
superPower(); // => Flying
function superPower() {
console.log('Flying');
}
}
- 詳細については、Ben Cherry による JavaScript Scoping & Hoisting を参照してください。
比較演算子と等価性
-
15.2
if文などの条件文は、ToBoolean抽象メソッドによる強制型変換を使用して式を評価し、常に以下の単純なルールに従います:
- オブジェクト は true と評価されます
- Undefined は false と評価されます
- Null は false と評価されます
- ブール値 は そのブール値 と評価されます
- 数値 は +0, -0, NaN の場合は false、それ以外は true と評価されます
- 文字列 は空文字
''の場合は false、それ以外は true と評価されます
if ([0] && []) {
// true
// an array (even an empty one) is an object, objects will evaluate to true
}
- 15.3 ショートカットを使用してください。
// bad
if (name !== '') {
// ...stuff...
}
// good
if (name) {
// ...stuff...
}
// bad
if (collection.length > 0) {
// ...stuff...
}
// good
if (collection.length) {
// ...stuff...
}
- 15.4 詳細については、Angus Croll による Truth Equality and JavaScript を参照してください。
- 15.5 レキシカル宣言(
let、const、function、classなど)を含むcaseやdefault節では、ブロックを作成するために中括弧を使用してください。
なぜなら、レキシカル宣言は
switchブロック全体で可視ですが、初期化されるのは割り当て時のみであり、それはそのcaseに到達したときだけだからです。複数のcase節が同じものを定義しようとすると問題が発生します。
eslint rules: no-case-declarations.
// bad
switch (foo) {
case 1:
let x = 1;
break;
case 2:
const y = 2;
break;
case 3:
function f() {}
break;
default:
class C {}
}
// good
switch (foo) {
case 1: {
let x = 1;
break;
}
case 2: {
const y = 2;
break;
}
case 3: {
function f() {}
break;
}
case 4:
bar();
break;
default: {
class C {}
}
}
- 15.7 三項演算子はネストすべきではなく、通常は1行の式にするべきです。
eslint rules: no-nested-ternary.
// bad
const foo = maybe1 > maybe2
? "bar"
: value1 > value2 ? "baz" : null;
// better
const maybeNull = value1 > value2 ? 'baz' : null;
const foo = maybe1 > maybe2
? 'bar'
: maybeNull;
// best
const maybeNull = value1 > value2 ? 'baz' : null;
const foo = maybe1 > maybe2 ? 'bar' : maybeNull;
- 15.8 不要な三項演算子は避けてください。
eslint rules: no-unneeded-ternary.
// bad
const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;
// good
const foo = a || b;
const bar = !!c;
const baz = !c;
ブロック
- 16.1 すべての複数行ブロックには中括弧を使用してください。
// bad
if (test)
return false;
// good
if (test) return false;
// good
if (test) {
return false;
}
// bad
function foo() { return false; }
// good
function bar() {
return false;
}
- 16.2
ifとelseを使った複数行ブロックを使用する場合は、elseをifブロックの閉じ括弧と同じ行に置いてください。eslint:brace-stylejscs:disallowNewlineBeforeBlockStatements
// bad
if (test) {
thing1();
thing2();
}
else {
thing3();
}
// good
if (test) {
thing1();
thing2();
} else {
thing3();
}
制御文
- 17.1 制御文(
if,whileなど)が長くなりすぎたり、最大行長を超える場合は、各(グループ化された)条件を新しい行に置くことができます。論理演算子は行の先頭に置くべきです。
なぜなら、演算子を行頭に置くことで演算子の位置が揃い、メソッドチェーンと同様のパターンに従うことができるからです。また、複雑なロジックを視覚的に把握しやすくなり、可読性が向上します。
// bad
if ((foo === 123 || bar === 'abc') && doesItLookGoodWhenItBecomesThatLong() && isThisReallyHappening()) {
thing1();
}
// bad
if (foo === 123 &&
bar === 'abc') {
thing1();
}
// bad
if (foo === 123
&& bar === 'abc') {
thing1();
}
// bad
if (
foo === 123 &&
bar === 'abc'
) {
thing1();
}
// good
if (
foo === 123
&& bar === 'abc'
) {
thing1();
}
// good
if (
(foo === 123 || bar === 'abc')
&& doesItLookGoodWhenItBecomesThatLong()
&& isThisReallyHappening()
) {
thing1();
}
// good
if (foo === 123 && bar === 'abc') {
thing1();
}
- 17.2 制御文の代わりに選択演算子を使用しないでください。
// bad
!isRunning && startRunning();
// good
if (!isRunning) {
startRunning();
}
コメント
- 18.1 複数行のコメントには
/** ... */を使用してください。説明を含め、すべてのパラメータと戻り値の型と値を指定してください。
// bad
// make() returns a new element
// based on the passed in tag name
//
// @param {String} tag
// @return {Element} element
function make(tag) {
// ...stuff...
return element;
}
// good
/**
* make() returns a new element
* based on the passed in tag name
*
* @param {String} tag
* @return {Element} element
*/
function make(tag) {
// ...stuff...
return element;
}
- 18.2 1行コメントには
//を使用してください。1行コメントは、コメントの対象となる行の上に新しい行で配置してください。ブロックの最初の行でない限り、コメントの前には空行を入れてください。
// bad
const active = true; // is current tab
// good
// is current tab
const active = true;
// bad
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
const type = this._type || 'no type';
return type;
}
// good
function getType() {
console.log('fetching type...');
// set the default type to 'no type'
const type = this._type || 'no type';
return type;
}
// also good
function getType() {
// set the default type to 'no type'
const type = this._type || 'no type';
return type;
}
-
18.3 コメントの先頭に
FIXMEやTODOを付けると、他の開発者が、再検討が必要な問題を指摘しているのか、実装が必要な解決策を提案しているのかを素早く理解するのに役立ちます。これらは通常のコメントとは異なり、実行可能(actionable)です。アクションはFIXME: -- これを解決する必要があるまたはTODO: -- これを実装する必要があるです。 -
18.4 問題を注釈するには
// FIXME:を使用してください。
class Calculator extends Abacus {
constructor() {
super();
// FIXME: shouldn't use a global here
total = 0;
}
}
- 18.5 問題の解決策を注釈するには
// TODO:を使用してください。
class Calculator extends Abacus {
constructor() {
super();
// TODO: total should be configurable by an options param
this.total = 0;
}
}
空白
- 19.1 ソフトタブ(スペース文字)を使用し、2スペースに設定してください。eslint:
indentjscs:validateIndentation
// bad
function foo() {
∙∙∙∙const name;
}
// bad
function bar() {
∙const name;
}
// good
function baz() {
∙∙const name;
}
- 19.2 開始中括弧の前にスペースを1つ置いてください。eslint:
space-before-blocksjscs:requireSpaceBeforeBlockStatements
// bad
function test(){
console.log('test');
}
// good
function test() {
console.log('test');
}
// bad
dog.set('attr',{
age: '1 year',
breed: 'Bernese Mountain Dog',
});
// good
dog.set('attr', {
age: '1 year',
breed: 'Bernese Mountain Dog',
});
- 19.3 制御文(
if,whileなど)の開き括弧の前にはスペースを1つ置いてください。関数呼び出しや各宣言の引数リストと関数名の間にはスペースを入れないでください。eslint:space-after-keywords,space-before-keywordsjscs:requireSpaceAfterKeywords
// bad
if(isJedi) {
fight ();
}
// good
if (isJedi) {
fight();
}
// bad
function fight () {
console.log ('Swooosh!');
}
// good
function fight() {
console.log('Swooosh!');
}
- 19.4 演算子の間にはスペースを入れてください。eslint:
space-infix-opsjscs:requireSpaceBeforeBinaryOperators,requireSpaceAfterBinaryOperators
// bad
const x=y+5;
// good
const x = y + 5;
- 19.5 ファイルの末尾は単一の改行文字で終了してください。
// bad
(function (global) {
// ...stuff...
})(this);
// bad
(function (global) {
// ...stuff...
})(this);↵
↵
// good
(function (global) {
// ...stuff...
})(this);↵
- 19.6 長いメソッドチェーン(2つ以上のメソッドチェーン)を作成する場合は、インデントを使用してください。先頭にドットを使用することで、その行が新しい文ではなくメソッド呼び出しであることを強調します。eslint:
newline-per-chained-callno-whitespace-before-property
// bad
$('#items').find('.selected').highlight().end().find('.open').updateCount();
// bad
$('#items').
find('.selected').
highlight().
end().
find('.open').
updateCount();
// good
$('#items')
.find('.selected')
.highlight()
.end()
.find('.open')
.updateCount();
// 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) + ')')
.call(tron.led);
// good
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) + ')')
.call(tron.led);
// good
const leds = stage.selectAll('.led').data(data);
- 19.7 ブロックの後、次の文の前には空行を入れてください。jscs:
requirePaddingNewLinesAfterBlocks
// bad
if (foo) {
return bar;
}
return baz;
// good
if (foo) {
return bar;
}
return baz;
// bad
const obj = {
foo() {
},
bar() {
},
};
return obj;
// good
const obj = {
foo() {
},
bar() {
},
};
return obj;
// bad
const arr = [
function foo() {
},
function bar() {
},
];
return arr;
// good
const arr = [
function foo() {
},
function bar() {
},
];
return arr;
- 19.8 ブロック内を空行でパディングしないでください。eslint:
padded-blocksjscs:disallowPaddingNewlinesInBlocks
// bad
function bar() {
console.log(foo);
}
// also bad
if (baz) {
console.log(qux);
} else {
console.log(foo);
}
// good
function bar() {
console.log(foo);
}
// good
if (baz) {
console.log(qux);
} else {
console.log(foo);
}
- 19.9 括弧の内側に空白を追加しないでください。eslint:
space-in-parensjscs:disallowSpacesInsideParentheses
// bad
function bar( foo ) {
return foo;
}
// good
function bar(foo) {
return foo;
}
// bad
if ( foo ) {
console.log(foo);
}
// good
if (foo) {
console.log(foo);
}
- 19.10 ブラケット(角括弧)の内側に空白を追加しないでください。eslint:
array-bracket-spacingjscs:disallowSpacesInsideArrayBrackets
// bad
const foo = [ 1, 2, 3 ];
console.log(foo[ 0 ]);
// good
const foo = [1, 2, 3];
console.log(foo[0]);
- 19.11 波括弧の内側には空白を追加してください。eslint:
object-curly-spacingjscs: [disallowSpacesInsideObjectBrackets](http://jscs.info/rule/
// bad
const foo = {clark: 'kent'};
// good
const foo = { clark: 'kent' };
- 19.12 行の長さは100文字(空白を含む)を超えないようにしてください。eslint:
max-lenjscs:maximumLineLength
なぜなら、可読性と保守性が確保されるからです。
// bad
const foo = 'Whatever national crop flips the window. The cartoon reverts within the screw. Whatever wizard constrains a helpful ally. The counterpart ascends!';
// 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!';
// good
$.ajax({
method: 'POST',
url: 'https://airbnb.com/',
data: { name: 'John' },
})
.done(() => console.log('Congratulations!'))
.fail(() => console.log('You have failed this city.'));
カンマ
- 20.1 先頭のカンマ: **ダメです。**eslint:
comma-stylejscs:requireCommaBeforeLineBreak
// bad
const story = [
once
, upon
, aTime
];
// good
const story = [
once,
upon,
aTime,
];
// bad
const hero = {
firstName: 'Ada'
, lastName: 'Lovelace'
, birthYear: 1815
, superPower: 'computers'
};
// good
const hero = {
firstName: 'Ada',
lastName: 'Lovelace',
birthYear: 1815,
superPower: 'computers',
};
- 20.2 末尾のカンマの追加: **いいですね。**eslint:
comma-danglejscs:requireTrailingComma
なぜなら、これにより Git の差分がきれいになるからです。また、Babel などのトランスパイラはトランスパイル後のコードで余分な末尾のカンマを削除するため、レガシーブラウザにおける 末尾のカンマの問題 を心配する必要がありません。
// bad - git diff without trailing comma
const hero = {
firstName: 'Florence',
lastName: 'Nightingale'
+ lastName: 'Nightingale',
+ inventorOf: ['coxcomb graph', 'modern nursing']
};
// good - git diff with trailing comma
const hero = {
firstName: 'Florence',
lastName: 'Nightingale',
+ inventorOf: ['coxcomb chart', 'modern nursing'],
};
// bad
const hero = {
firstName: 'Dana',
lastName: 'Scully'
};
const heroes = [
'Batman',
'Superman'
];
// good
const hero = {
firstName: 'Dana',
lastName: 'Scully',
};
const heroes = [
'Batman',
'Superman',
];
セミコロン
- 21.1 **はい。**eslint:
semijscs:requireSemicolons
// bad
(function () {
const name = 'Skywalker'
return name
})()
// good
(() => {
const name = 'Skywalker';
return name;
}());
// good (guards against the function becoming an argument when two files with IIFEs are concatenated)
;(() => {
const name = 'Skywalker';
return name;
}());
型変換と強制
// => this.reviewScore = 9;
// bad
const totalScore = this.reviewScore + '';
// good
const totalScore = String(this.reviewScore);
const inputValue = '4';
// bad
const val = new Number(inputValue);
// bad
const val = +inputValue;
// bad
const val = inputValue >> 0;
// bad
const val = parseInt(inputValue);
// good
const val = Number(inputValue);
// good
const val = parseInt(inputValue, 10);
- 22.4 何らかの理由でクレイジーなことをしていて
parseIntがボトルネックになっており、パフォーマンス上の理由 でビットシフトを使用する必要がある場合は、その理由と行っている内容を説明するコメントを残してください。
// good
/**
* parseInt was the reason my code was slow.
* Bitshifting the String to coerce it to a
* Number made it a lot faster.
*/
const val = inputValue >> 0;
- 22.5 注意: ビットシフト操作を使用する場合は注意してください。数値は 64ビット値 として表現されますが、ビットシフト操作は常に32ビット整数を返します (source)。ビットシフトは、32ビットを超える整数値に対して予期しない動作を引き起こす可能性があります。Discussion。符号付き32ビット整数の最大値は 2,147,483,647 です:
2147483647 >> 0 //=> 2147483647
2147483648 >> 0 //=> -2147483648
2147483649 >> 0 //=> -2147483647
- 22.6 ブール値:
const age = 0;
// bad
const hasAge = new Boolean(age);
// good
const hasAge = Boolean(age);
// good
const hasAge = !!age;
命名規則
- 23.1 1文字の名前は避けてください。名前は説明的にしてください。
// bad
function q() {
// ...stuff...
}
// good
function query() {
// ..stuff..
}
- 23.2 オブジェクト、関数、インスタンスの名前にはキャメルケース(camelCase)を使用してください。eslint:
camelcasejscs:requireCamelCaseOrUpperCaseIdentifiers
// bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}
// good
const thisIsMyObject = {};
function thisIsMyFunction() {}
- 23.3 コンストラクタやクラスの名前にのみパスカルケース(PascalCase)を使用してください。eslint:
new-capjscs:requireCapitalizedConstructors
// bad
function user(options) {
this.name = options.name;
}
const bad = new user({
name: 'nope',
});
// good
class User {
constructor(options) {
this.name = options.name;
}
}
const good = new User({
name: 'yup',
});
- 23.4 プライベートプロパティに名前を付けるときは、先頭にアンダースコア
_を使用してください。eslint:no-underscore-danglejscs:disallowDanglingUnderscores
// bad
this.__firstName__ = 'Panda';
this.firstName_ = 'Panda';
// good
this._firstName = 'Panda';
- 23.5
thisへの参照を保存しないでください。アロー関数または Function#bind を使用してください。jscs:disallowNodeTypes
// bad
function foo() {
const self = this;
return function () {
console.log(self);
};
}
// bad
function foo() {
const that = this;
return function () {
console.log(that);
};
}
// good
function foo() {
return () => {
console.log(this);
};
}
- 23.6 ファイルが単一のクラスをエクスポートする場合は、ファイル名はクラス名と完全に一致させてください。
// file contents
class CheckBox {
// ...
}
export default CheckBox;
// in some other file
// bad
import CheckBox from './checkBox';
// bad
import CheckBox from './check_box';
// good
import CheckBox from './CheckBox';
- 23.7 デフォルトの関数をエクスポートする場合はキャメルケースを使用してください。ファイル名は関数名と同じにしてください。
function makeStyleGuide() {
}
export default makeStyleGuide;
- 23.8 シングルトン / 関数ライブラリ / 空のオブジェクトをエクスポートする場合はパスカルケースを使用してください。
const AirbnbStyleGuide = {
es6: {
}
};
export default AirbnbStyleGuide;
アクセサ
- 24.1 プロパティのアクセサ関数は必須ではありません。
- 24.2 JavaScript のゲッター/セッターは使用しないでください。これらは予期しない副作用を引き起こし、テストや保守、推論が難しくなるためです。代わりに、アクセサ関数を作成する場合は、getVal() や setVal(‘hello’) を使用してください。
// bad
dragon.age();
// good
dragon.getAge();
// bad
dragon.age(25);
// good
dragon.setAge(25);
- 24.3 プロパティがブール値の場合は、
isVal()またはhasVal()を使用してください。
// bad
if (!dragon.age()) {
return false;
}
// good
if (!dragon.hasAge()) {
return false;
}
- 24.4 get() および set() 関数を作成しても構いませんが、一貫性を持たせてください。
class Jedi {
constructor(options = {}) {
const lightsaber = options.lightsaber || 'blue';
this.set('lightsaber', lightsaber);
}
set(key, val) {
this[key] = val;
}
get(key) {
return this[key];
}
}
イベント
- 25.1 イベントにデータペイロードを添付する場合(DOM イベントであれ、Backbone イベントのような独自のイベントであれ)、生の値ではなくハッシュ(オブジェクト)を渡してください。これにより、後の貢献者がイベントのすべてのハンドラを見つけて更新することなく、イベントペイロードにデータを追加できます。例えば、次のような書き方ではなく:
// bad
$(this).trigger('listingUpdated', listing.id);
...
$(this).on('listingUpdated', (e, listingId) => {
// do something with listingId
});
次のように書いてください:
// good
$(this).trigger('listingUpdated', { listingId: listing.id });
...
$(this).on('listingUpdated', (e, data) => {
// do something with data.listingId
});
jQuery
- 26.1 jQuery オブジェクト変数の先頭には
$を付けてください。jscs:requireDollarBeforejQueryAssignment
// bad
const sidebar = $('.sidebar');
// good
const $sidebar = $('.sidebar');
// good
const $sidebarBtn = $('.sidebar-btn');
- 26.2 jQuery の検索結果をキャッシュしてください。
// bad
function setSidebar() {
$('.sidebar').hide();
// ...stuff...
$('.sidebar').css({
'background-color': 'pink'
});
}
// good
function setSidebar() {
const $sidebar = $('.sidebar');
$sidebar.hide();
// ...stuff...
$sidebar.css({
'background-color': 'pink'
});
}
- 26.3 DOM クエリには、カスケード
$('.sidebar ul')または 親 > 子$('.sidebar > ul')を使用してください。jsPerf - 26.4 スコープ付き jQuery オブジェクトクエリで
findを使用してください。
// bad
$('ul', '.sidebar').hide();
// bad
$('.sidebar').find('ul').hide();
// good
$('.sidebar ul').hide();
// good
$('.sidebar > ul').hide();
// good
$sidebar.find('ul').hide();
ECMAscript 5 互換性
ECMAScript 6 スタイル
- 28.1 以下は、様々な ES6 機能へのリンク集です。
- アロー関数
- クラス
- オブジェクトの短縮表記
- オブジェクトの簡潔表記
- 計算されたオブジェクトプロパティ
- テンプレート文字列
- 分割代入
- デフォルトパラメータ
- Rest
- 配列スプレッド
- Let と Const
- イテレータとジェネレータ
- モジュール
標準ライブラリ
標準ライブラリ には、機能が壊れているものの、レガシーな理由で残されている機能的ユーティリティがいくつか含まれています。
- 29.1
isNaNの代わりにNumber.isNaNを使用してください。
なぜなら、
isNaNは非数値を数値に強制変換し、NaN に変換されるものすべてに対して true を返すからです。 もしこの動作が望ましい場合は、明示的に行ってください。
// bad
isNaN('1.2'); // false
isNaN('1.2.3'); // true
// good
Number.isNaN('1.2.3'); // false
Number.isNaN(Number('1.2.3')); // true
- 29.2
isFiniteの代わりにNumber.isFiniteを使用してください。
なぜなら、
isFiniteは非数値を数値に強制変換し、有限数に変換されるものすべてに対して true を返すからです。 もしこの動作が望ましい場合は、明示的に行ってください。
// bad
isFinite('2e3'); // true
// good
Number.isFinite('2e3'); // false
Number.isFinite(parseInt('2e3', 10)); // true
テスト
- 30.1 はい。
function foo() {
return true;
}
- 30.2 冗談はさておき:
- どのテストフレームワークを使用するにしても、テストを書くべきです!
- 多くの小さな純粋関数を書くように努め、変更(mutation)が発生する場所を最小限に抑えてください。
- スタブやモックには注意してください - テストが脆くなる可能性があります。
- Airbnb では主に
mochaを使用しています。tapeも小さな独立したモジュールで時々使用されます。 - 100% のテストカバレッジを目指すことは良い目標ですが、常にそれが現実的であるとは限りません。
- バグを修正するたびに、回帰テストを書いてください。回帰テストなしで修正されたバグは、将来ほぼ確実に再び発生します。
パフォーマンス
- On Layout & Web Performance
- String vs Array Concat
- Try/Catch Cost In a Loop
- Bang Function
- jQuery Find vs Context, Selector
- innerHTML vs textContent for script text
- Long String Concatenation
- Loading…
リソース
Learning ES6
- Draft ECMA 2015 (ES6) Spec
- ExploringJS
- ES6 Compatibility Table
- Comprehensive Overview of ES6 Features
Read This
Tools
- Code Style Linters
Other Style Guides
- Google JavaScript Style Guide
- jQuery Core Style Guidelines
- Principles of Writing Consistent, Idiomatic JavaScript
Other Styles
- Naming this in nested functions - Christian Johansen
- Conditional Callbacks - Ross Allen
- Popular JavaScript Coding Conventions on Github - JeongHoon Byun
- Multiple var statements in JavaScript, not superfluous - Ben Alman
Further Reading
- Understanding JavaScript Closures - Angus Croll
- Basic JavaScript for the impatient programmer - Dr. Axel Rauschmayer
- You Might Not Need jQuery - Zack Bloom & Adam Schwartz
- ES6 Features - Luke Hoban
- Frontend Guidelines - Benjamin De Cock
Books
- JavaScript: The Good Parts - Douglas Crockford
- JavaScript Patterns - Stoyan Stefanov
- Pro JavaScript Design Patterns - Ross Harmes and Dustin Diaz
- High Performance Web Sites: Essential Knowledge for Front-End Engineers - Steve Souders
- Maintainable JavaScript - Nicholas C. Zakas
- JavaScript Web Applications - Alex MacCaw
- Pro JavaScript Techniques - John Resig
- Smashing Node.js: JavaScript Everywhere - Guillermo Rauch
- Secrets of the JavaScript Ninja - John Resig and Bear Bibeault
- Human JavaScript - Henrik Joreteg
- Superhero.js - Kim Joar Bekkelund, Mads Mobæk, & Olav Bjorkoy
- JSBooks - Julien Bouquillon
- Third Party JavaScript - Ben Vinegar and Anton Kovalyov
- Effective JavaScript: 68 Specific Ways to Harness the Power of JavaScript - David Herman
- Eloquent JavaScript - Marijn Haverbeke
- You Don’t Know JS: ES6 & Beyond - Kyle Simpson
Blogs
- DailyJS
- JavaScript Weekly
- JavaScript, JavaScript…
- Bocoup Weblog
- Adequately Good
- NCZOnline
- Perfection Kills
- Ben Alman
- Dmitry Baranovskiy
- Dustin Diaz
- nettuts
Podcasts
採用企業
これは、このスタイルガイドを使用している企業のリストです。もし使用している場合は、プルリクエストを送って追加してください。
- Aan Zee: AanZee/javascript
- Adult Swim: adult-swim/javascript
- Airbnb: airbnb/javascript
- Apartmint: apartmint/javascript
- Avalara: avalara/javascript
- Avant: avantcredit/javascript
- Billabong: billabong/javascript
- Bisk: bisk/javascript
- Blendle: blendle/javascript
- Brainshark: brainshark/javascript
- ComparaOnline: comparaonline/javascript
- Compass Learning: compasslearning/javascript-style-guide
- DailyMotion: dailymotion/javascript
- Digitpaint digitpaint/javascript
- Ecosia: ecosia/javascript
- Evernote: evernote/javascript-style-guide
- Evolution Gaming: evolution-gaming/javascript
- ExactTarget: ExactTarget/javascript
- Expensify Expensify/Style-Guide
- Flexberry: Flexberry/javascript-style-guide
- Gawker Media: gawkermedia/javascript
- General Electric: GeneralElectric/javascript
- GoodData: gooddata/gdc-js-style
- Grooveshark: grooveshark/javascript
- How About We: howaboutwe/javascript
- Huballin: huballin/javascript
- HubSpot: HubSpot/javascript
- Hyper: hyperoslo/javascript-playbook
- InfoJobs: InfoJobs/JavaScript-Style-Guide
- Intent Media: intentmedia/javascript
- Jam3: Jam3/Javascript-Code-Conventions
- JeopardyBot: kesne/jeopardy-bot
- JSSolutions: JSSolutions/javascript
- Kinetica Solutions: kinetica/javascript
- Mighty Spring: mightyspring/javascript
- MinnPost: MinnPost/javascript
- MitocGroup: MitocGroup/javascript
- ModCloth: modcloth/javascript
- Money Advice Service: moneyadviceservice/javascript
- Muber: muber/javascript
- National Geographic: natgeo/javascript
- National Park Service: nationalparkservice/javascript
- Nimbl3: nimbl3/javascript
- Orion Health: orionhealth/javascript
- OutBoxSoft: OutBoxSoft/javascript
- Peerby: Peerby/javascript
- Razorfish: razorfish/javascript-style-guide
- reddit: reddit/styleguide/javascript
- React: /facebook/react/blob/master/CONTRIBUTING.md#style-guide
- REI: reidev/js-style-guide
- Ripple: ripple/javascript-style-guide
- SeekingAlpha: seekingalpha/javascript-style-guide
- Shutterfly: shutterfly/javascript
- Springload: springload/javascript
- StudentSphere: studentsphere/javascript
- Target: target/javascript
- TheLadders: TheLadders/javascript
- T4R Technology: T4R-Technology/javascript
- VoxFeed: VoxFeed/javascript-style-guide
- WeBox Studio: weboxstudio/javascript
- Weggo: Weggo/javascript
- Zillow: zillow/javascript
- ZocDoc: ZocDoc/javascript
翻訳
このスタイルガイドは他の言語でも利用可能です:
Brazilian Portuguese: armoucar/javascript-style-guide
Bulgarian: borislavvv/javascript
Catalan: fpmweb/javascript-style-guide
Chinese (Simplified): sivan/javascript-style-guide
Chinese (Traditional): jigsawye/javascript
French: nmussy/javascript-style-guide
German: timofurrer/javascript-style-guide
Italian: sinkswim/javascript-style-guide
Japanese: mitsuruog/javacript-style-guide
Korean: tipjs/javascript-style-guide
Polish: mjurczyk/javascript
Russian: uprock/javascript
Spanish: paolocarrasco/javascript-style-guide
Thai: lvarayut/javascript-style-guide
JavaScript スタイルガイドガイド
JavaScript についてチャットする
- Find us on gitter.
コントリビューター
License
(The MIT License)
Copyright (c) 2014-2016 Airbnb
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Amendments
We encourage you to fork this guide and change the rules to fit your team’s style guide. Below, you may list some amendments to the style guide. This allows you to periodically update your style guide without having to deal with merge conflicts.