Photo by Pankaj Patel on Unsplash
Guia de Estilo JavaScript do Airbnb()
Uma abordagem na sua maioria razoável para JavaScript.
Outros Guias de Estilo
Traduzido de Airbnb JavaScript Style Guide.
Tipos (Types)
- 1.1 Primitivos (Primitives): Você acessa tipos primitivos diretamente.
stringnumberbooleannullundefined
const foo = 1;
let bar = foo;
bar = 9;
console.log(foo, bar); // => 1, 9
- 1.2 Complexos (Complex): Você acessa tipos complexos por referência (by reference).
objectarrayfunction
const foo = [1, 2];
const bar = foo;
bar[0] = 9;
console.log(foo[0], bar[0]); // => 9, 9
Referências (References)
- 2.1 Use
constpara todas as suas referências; evite usarvar. eslint:prefer-const,no-const-assign
Por quê? Isso garante que você não possa reatribuir suas referências, o que pode levar a bugs e código difícil de compreender.
// bad
var a = 1;
var b = 2;
// good
const a = 1;
const b = 2;
- 2.2 Se você precisar reatribuir referências, use
letem vez devar. eslint:no-varjscs:disallowVar
Por quê?
lettem escopo de bloco (block-scoped), enquantovartem escopo de função (function-scoped).
// bad
var count = 1;
if (true) {
count += 1;
}
// good, use the let.
let count = 1;
if (true) {
count += 1;
}
- 2.3 Note que tanto
letquantoconsttêm escopo de bloco.
// const e let existem apenas dentro dos blocos onde são definidos.
{
let a = 1;
const b = 1;
}
console.log(a); // ReferenceError
console.log(b); // ReferenceError
Objetos (Objects)
- 3.1 Use a sintaxe literal para a criação de objetos. eslint rules:
no-new-object.
// bad
const item = new Object();
// good
const item = {};
- 3.2 Não use palavras reservadas como chaves. Não funcionará no IE8. Mais info. No entanto, não há problema em usá-las em módulos ES6 e código server-side. jscs:
disallowIdentifierNames
// bad
const superman = {
default: { clark: 'kent' },
private: true,
};
// good
const superman = {
defaults: { clark: 'kent' },
hidden: true,
};
- 3.3 Use sinônimos legíveis no lugar de palavras reservadas. jscs:
disallowIdentifierNames
// bad
const superman = {
class: 'alien',
};
// bad
const superman = {
klass: 'alien',
};
// good
const superman = {
type: 'alien',
};
- 3.4 Use nomes de propriedades computados (computed property names) ao criar objetos com nomes de propriedades dinâmicos.
Por quê? Eles permitem que você defina todas as propriedades do objeto em um só lugar.
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 Use a abreviação de métodos de objeto (object method shorthand). 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 Use a abreviação de valores de propriedade (property value shorthand). eslint:
object-shorthandjscs:requireEnhancedObjectLiterals
Por quê? É mais curto e descritivo.
const lukeSkywalker = 'Luke Skywalker';
// bad
const obj = {
lukeSkywalker: lukeSkywalker,
};
// good
const obj = {
lukeSkywalker,
};
- 3.7 Agrupe suas abreviações no início da sua declaração de objeto.
Por quê? É mais fácil saber quais propriedades estão usando a abreviação.
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 Apenas coloque aspas nas propriedades que são identificadores inválidos. eslint:
quote-propsjscs:disallowQuotedKeysInObjects
Por quê? Em geral, nós consideramos isso subjetivamente mais fácil de ler. Melhora o destaque de sintaxe e também é mais fácil de ser otimizado por muitas engines de JS.
// bad
const bad = {
'foo': 3,
'bar': 4,
'data-blah': 5,
};
// good
const good = {
foo: 3,
bar: 4,
'data-blah': 5,
};
Arrays (Arrays)
- 4.1 Use a sintaxe literal para a criação de arrays. eslint:
no-array-constructor
// bad
const items = new Array();
// good
const items = [];
- 4.2 Use Array#push em vez de atribuição direta para adicionar itens a um array.
const someStack = [];
// bad
someStack[someStack.length] = 'abracadabra';
// good
someStack.push('abracadabra');
- 4.3 Use spreads de array
...para copiar arrays.
// 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 Para converter um objeto do tipo array (array-like object) para um array, use Array#from.
const foo = document.querySelectorAll('.foo');
const nodes = Array.from(foo);
- 4.5 Use declarações de retorno em callbacks de métodos de array. Tudo bem omitir o retorno se o corpo da função consistir em uma única declaração seguindo 8.2. 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;
});
Desestruturação (Destructuring)
- 5.1 Use a desestruturação de objetos ao acessar e usar múltiplas propriedades de um objeto. jscs:
requireObjectDestructuring
Por quê? A desestruturação evita que você crie referências temporárias para essas propriedades.
// 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 Use a desestruturação de array. jscs:
requireArrayDestructuring
const arr = [1, 2, 3, 4];
// bad
const first = arr[0];
const second = arr[1];
// good
const [first, second] = arr;
- 5.3 Use a desestruturação de objetos para múltiplos valores de retorno, não a desestruturação de array.
Por quê? Você pode adicionar novas propriedades ou mudar a ordem das coisas sem quebrar os locais de chamada (call sites).
// 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);
Strings (Strings)
- 6.1 Use aspas simples
''para strings. eslint:quotesjscs:validateQuoteMarks
// bad
const name = "Capt. Janeway";
// good
const name = 'Capt. Janeway';
- 6.2 Strings que fazem a linha ultrapassar 100 caracteres não devem ser escritas em várias linhas usando concatenação de string.
- 6.3 Nota: Se usado excessivamente, strings longas com concatenação podem impactar a performance. jsPerf & Discussão.
// 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 Ao construir strings programmaticamente, use template strings em vez de concatenação. eslint:
prefer-templatetemplate-curly-spacingjscs:requireTemplateStrings
Por quê? Template strings dão a você uma sintaxe legível e concisa com quebras de linha e recursos de interpolação de string.
// 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 Nunca use
eval()em uma string, isso abre muitas vulnerabilidades.
Funções (Functions)
- 7.1 Use declarações de função (function declarations) em vez de expressões de função (function expressions). jscs:
requireFunctionDeclarations
Por quê? As declarações de função são nomeadas, então são mais fáceis de identificar em stack traces. Além disso, as declarações de função são hoisted, enquanto as expressões de função não são. Essa regra facilita que as Arrow Functions substituam completamente as expressões de função.
// bad
const foo = function () {
};
// good
function foo() {
}
- 7.2 IIFE: eslint:
wrap-iifejscs:requireParenthesesAroundIIFE
Por quê? Uma IIFE é uma unidade única - envolver a função e sua invocação em parênteses torna isso claro. Note que em um mundo com módulos, você quase não precisa de IIFE.
// immediately-invoked function expression (IIFE)
(function () {
console.log('Welcome to the Internet. Please follow me.');
}());
-
7.3 Nunca declare uma função em um bloco não-função (if, while, etc). Atribua a função a uma variável em vez disso. Navegadores permitirão que você faça isso, mas todos interpretam de forma diferente. eslint:
no-loop-func -
7.4 Nota: ECMA-262 define um
blococomo uma lista de declarações. Uma declaração de função não é uma declaração. Leia a nota do ECMA-262 sobre essa questão.
// bad
if (currentUser) {
function test() {
console.log('Nope.');
}
}
// good
let test;
if (currentUser) {
test = () => {
console.log('Yup.');
};
}
- 7.5 Nunca nomeie um parâmetro
arguments. Isso terá precedência sobre o objetoargumentsque é dado a cada escopo de função.
// bad
function nope(name, options, arguments) {
// ...stuff...
}
// good
function yup(name, options, args) {
// ...stuff...
}
- 7.6 Nunca use
arguments, opte por usar a sintaxe rest...em vez disso.prefer-rest-params
Por quê?
...é explícito sobre quais argumentos você quer puxar. Além disso, argumentos rest são um Array real, e não meramente Array-like comoarguments.
// bad
function concatenateAll() {
const args = Array.prototype.slice.call(arguments);
return args.join('');
}
// good
function concatenateAll(...args) {
return args.join('');
}
- 7.7 Use a sintaxe de parâmetros padrão em vez de modificar os argumentos da função.
// 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 Evite efeitos colaterais com parâmetros padrão.
Por quê? Eles são confusos de entender.
var b = 1;
// bad
function count(a = b++) {
console.log(a);
}
count(); // 1
count(); // 2
count(3); // 3
count(); // 3
- 7.9 Sempre coloque os parâmetros padrão por último.
// bad
function handleThings(opts = {}, name) {
// ...
}
// good
function handleThings(name, opts = {}) {
// ...
}
- 7.10 Nunca use o construtor Function para criar uma nova função.
Por quê? Criar uma função dessa maneira avalia uma string de forma similar ao eval(), o que abre vulnerabilidades.
// bad
var add = new Function('a', 'b', 'return a + b');
// still bad
var subtract = Function('a', 'b', 'return a - b');
- 7.11 Espaçamento na assinatura de uma função.
Por quê? A consistência é boa, e você não deveria ter que adicionar ou remover espaços ao adicionar ou remover um nome.
// bad
const f = function(){};
const g = function (){};
const h = function() {};
// good
const x = function () {};
const y = function a() {};
- 7.12 Nunca modifique parâmetros. eslint:
no-param-reassign
Por quê? Manipular objetos passados como parâmetros pode causar efeitos colaterais indesejados no chamador original.
// bad
function f1(obj) {
obj.key = 1;
};
// good
function f2(obj) {
const key = Object.prototype.hasOwnProperty.call(obj, 'key') ? obj.key : 1;
};
- 7.13 Nunca reatribua parâmetros. eslint:
no-param-reassign
Por quê? Reatribuir parâmetros pode levar a comportamentos inesperados, especialmente ao acessar o objeto
arguments. Isso também pode causar problemas de otimização, especialmente no 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) {
}
```
Arrow Functions
- 8.1 Quando você deve usar uma expressão de função (como ao passar uma função anônima), use a notação de arrow function. eslint:
prefer-arrow-callback,arrow-spacingjscs:requireArrowFunctions
Por quê? Cria uma versão da função que executa no contexto de
this, que é geralmente o que você quer, e é uma sintaxe mais concisa.
Por que não? Se você tem uma função bastante complexa, você pode mover essa lógica para sua própria declaração de função nomeada.
// 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 Se o corpo da função consiste em uma única declaração retornando uma expressão sem efeitos colaterais, omita as chaves e use o retorno implícito. Caso contrário, mantenha as chaves e use uma declaração
return. eslint:arrow-parens,arrow-body-stylejscs:disallowParenthesesAroundArrowParam,requireShorthandArrowFunctions
Por quê? Açúcar sintático (Syntactic sugar). É mais legível quando múltiplas funções são encadeadas juntas.
Por que não? Se você planeja retornar um objeto.
// 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 Caso a expressão se estenda por várias linhas, envolva-a em parênteses para melhor legibilidade.
Por quê? Mostra claramente onde a função começa e termina.
// 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 Se sua função recebe um único argumento e não usa chaves, omita os parênteses. Caso contrário, sempre inclua parênteses em torno dos argumentos. eslint:
arrow-parensjscs:disallowParenthesesAroundArrowParam
Por quê? Menos desordem visual.
// bad
[1, 2, 3].map((x) => x * x);
// good
[1, 2, 3].map(x => x * x);
// 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 Evite confundir a sintaxe de arrow function (
=>) com operadores de comparação (<=,>=). 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; }
Construtores (Constructors)
- 9.1 Sempre use
class. Evite manipularprototypediretamente.
Por quê? A sintaxe
classé mais concisa e mais fácil de raciocinar.
// 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 Use
extendspara herança.
Por quê? É uma maneira integrada de herdar a funcionalidade do protótipo sem quebrar
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 Métodos podem retornar
thispara ajudar com encadeamento de métodos (method chaining).
// 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 Tudo bem escrever um método toString() personalizado, apenas certifique-se de que funcione corretamente e não cause efeitos colaterais.
class Jedi {
constructor(options = {}) {
this.name = options.name || 'no name';
}
getName() {
return this.name;
}
toString() {
return `Jedi - ${this.getName()}`;
}
}
- 9.5 Classes têm um construtor padrão se um não for especificado. Um construtor vazio ou um que apenas delega para uma classe pai é desnecessário.
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';
}
}
Módulos (Modules)
- 10.1 Sempre use módulos (
import/export) em vez de um sistema de módulos não padrão. Você sempre pode transpilar para o seu sistema de módulos preferido.
Por quê? Módulos são o futuro, vamos começar a usar o futuro agora.
// 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 Não use importações com curingas (wildcard imports).
Por quê? Isso garante que você tenha um único default export.
// bad
import * as AirbnbStyleGuide from './AirbnbStyleGuide';
// good
import AirbnbStyleGuide from './AirbnbStyleGuide';
- 10.3 E não exporte diretamente de um import.
Por quê? Embora escrever em uma linha seja conciso, ter uma maneira clara de importar e uma maneira clara de exportar torna as coisas consistentes.
// bad
// filename es6.js
export { es6 as default } from './airbnbStyleGuide';
// good
// filename es6.js
import { es6 } from './AirbnbStyleGuide';
export default es6;
Iteradores e Geradores (Iterators and Generators)
- 11.1 Não use iteradores. Prefira as funções de ordem superior do JavaScript como
map()ereduce()em vez de loops comofor-of. eslint:no-iterator
Por quê? Isso impõe nossa regra de imutabilidade. Lidar com funções puras que retornam valores é mais fácil de raciocinar do que efeitos colaterais.
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 Não use geradores por enquanto.
Por quê? Eles não transpilam bem para ES5 ainda.
Propriedades (Properties)
- 12.1 Use a notação de ponto (dot notation) ao acessar propriedades. eslint:
dot-notationjscs:requireDotNotation
const luke = {
jedi: true,
age: 28,
};
// bad
const isJedi = luke['jedi'];
// good
const isJedi = luke.jedi;
- 12.2 Use a notação de colchetes
[]ao acessar propriedades com uma variável.
const luke = {
jedi: true,
age: 28,
};
function getProp(prop) {
return luke[prop];
}
const isJedi = getProp('jedi');
Variáveis (Variables)
- 13.1 Sempre use
constouletpara declarar variáveis. Não fazer isso resultará em variáveis globais. Queremos evitar poluir o namespace global. O Capitão Planeta nos avisou sobre isso.
// bad
superPower = new SuperPower();
// good
const superPower = new SuperPower();
- 13.2 Use uma declaração
constouletpor variável. eslint:one-varjscs:disallowMultipleVarDecl
Por quê? É mais fácil adicionar novas declarações de variáveis dessa maneira, e você nunca precisa se preocupar em trocar um
;por uma,ou introduzir diferenças apenas de pontuação.
// 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 Agrupe todos os seus
consts e depois agrupe todos os seuslets.
Por quê? Isso é útil quando mais tarde você precisar atribuir uma variável dependendo de uma das variáveis atribuídas anteriormente.
// 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 Atribua variáveis onde você precisa delas, mas coloque-as em um lugar razoável.
Por quê?
leteconsttêm escopo de bloco e não de função.
// 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;
}
Hoisting
- 14.1 Declarações
varsão hoisted (elevadas) para o topo do seu escopo, mas sua atribuição não. Declaraçõesconsteletsão abençoadas com um novo conceito chamado Zonas Mortas Temporais (TDZ). É importante saber por que typeof não é mais seguro.
// 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 Expressões de função anônimas elevam seu nome de variável, mas não a atribuição da função.
function example() {
console.log(anonymous); // => undefined
anonymous(); // => TypeError anonymous is not a function
var anonymous = function () {
console.log('anonymous function expression');
};
}
- 14.3 Expressões de função nomeadas elevam o nome da variável, não o nome da função ou o corpo da função.
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 Declarações de função elevam seu nome e o corpo da função.
function example() {
superPower(); // => Flying
function superPower() {
console.log('Flying');
}
}
- Para mais informações, consulte JavaScript Scoping & Hoisting por Ben Cherry.
Operadores de Comparação e Igualdade (Comparison Operators & Equality)
-
15.2 Declarações condicionais como
ifavaliam sua expressão usando coerção com o método abstratoToBooleane sempre seguem estas regras simples:
- Objects avaliam como true
- Undefined avalia como false
- Null avalia como false
- Booleans avaliam como o valor do booleano
- Numbers avaliam como false se forem +0, -0, ou NaN, caso contrário true
- Strings avaliam como false se for uma string vazia
'', caso contrário true
if ([0] && []) {
// true
// an array (even an empty one) is an object, objects will evaluate to true
}
- 15.3 Use atalhos.
// bad
if (name !== '') {
// ...stuff...
}
// good
if (name) {
// ...stuff...
}
// bad
if (collection.length > 0) {
// ...stuff...
}
// good
if (collection.length) {
// ...stuff...
}
- 15.4 Para mais informações, consulte Truth Equality and JavaScript por Angus Croll.
- 15.5 Use chaves para criar blocos em cláusulas
caseedefaultque contêm declarações léxicas (por exemplo,let,const,function, eclass).
Por quê? Declarações léxicas são visíveis em todo o bloco
switch, mas só são inicializadas quando atribuídas, o que só acontece quando seucaseé alcançado. Isso causa problemas quando múltiplas cláusulascasetentam definir a mesma coisa.
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 Ternários não devem ser aninhados e geralmente devem ser expressões de uma linha.
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 Evite declarações ternárias desnecessárias.
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;
Blocos (Blocks)
- 16.1 Use chaves com todos os blocos de múltiplas linhas.
// 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 Se você estiver usando blocos de múltiplas linhas com
ifeelse, coloqueelsena mesma linha que a chave de fechamento do blocoif. eslint:brace-stylejscs:disallowNewlineBeforeBlockStatements
// bad
if (test) {
thing1();
thing2();
}
else {
thing3();
}
// good
if (test) {
thing1();
thing2();
} else {
thing3();
}
Instruções de Controle (Control Statements)
- 17.1 No caso de sua instrução de controle (
if,whileetc.) ficar muito longa ou exceder o comprimento máximo da linha, cada condição (agrupada) pode ser colocada em uma nova linha. O operador lógico deve começar a linha.
Por quê? Exigir operadores no início da linha mantém os operadores alinhados e segue um padrão semelhante ao encadeamento de métodos. Isso também melhora a legibilidade, tornando a lógica complexa mais fácil de seguir visualmente.
// 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 Não use operadores de seleção em vez de instruções de controle.
// bad
!isRunning && startRunning();
// good
if (!isRunning) {
startRunning();
}
Comentários (Comments)
- 18.1 Use
/** ... */para comentários de múltiplas linhas. Inclua uma descrição, especifique tipos e valores para todos os parâmetros e valores de retorno.
// 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 Use
//para comentários de uma única linha. Coloque comentários de uma linha em uma nova linha acima do assunto do comentário. Coloque uma linha vazia antes do comentário, a menos que esteja na primeira linha de um bloco.
// 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 Prefixar seus comentários com
FIXMEouTODOajuda outros desenvolvedores a entender rapidamente se você está apontando um problema que precisa ser revisitado ou se você está sugerindo uma solução que precisa ser implementada. Estes são diferentes de comentários regulares porque são acionáveis. As ações sãoFIXME: -- need to figure this outouTODO: -- need to implement. -
18.4 Use
// FIXME:para anotar problemas.
class Calculator extends Abacus {
constructor() {
super();
// FIXME: shouldn't use a global here
total = 0;
}
}
- 18.5 Use
// TODO:para anotar soluções para problemas.
class Calculator extends Abacus {
constructor() {
super();
// TODO: total should be configurable by an options param
this.total = 0;
}
}
Espaços em Branco (Whitespace)
- 19.1 Use soft tabs (caractere de espaço) definidos como 2 espaços. eslint:
indentjscs:validateIndentation
// bad
function foo() {
∙∙∙∙const name;
}
// bad
function bar() {
∙const name;
}
// good
function baz() {
∙∙const name;
}
- 19.2 Coloque 1 espaço antes da chave de abertura. 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 Coloque 1 espaço antes do parêntese de abertura nas instruções de controle (
if,whileetc.). Não coloque espaço entre a lista de argumentos e o nome da função em chamadas e declarações de função. 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 Separe operadores com espaços. eslint:
space-infix-opsjscs:requireSpaceBeforeBinaryOperators,requireSpaceAfterBinaryOperators
// bad
const x=y+5;
// good
const x = y + 5;
- 19.5 Termine arquivos com uma única quebra de linha.
// bad
(function (global) {
// ...stuff...
})(this);
// bad
(function (global) {
// ...stuff...
})(this);↵
↵
// good
(function (global) {
// ...stuff...
})(this);↵
- 19.6 Use indentação ao fazer encadeamentos de métodos longos (mais de 2 cadeias de métodos). Use um ponto no início, o que enfatiza que a linha é uma chamada de método, não uma nova instrução. 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 Deixe uma linha em branco após blocos e antes da próxima instrução. 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 Não preencha seus blocos com linhas em branco. 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 Não adicione espaços dentro de parênteses. 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 Não adicione espaços dentro de colchetes. 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 Adicione espaços dentro de chaves. eslint:
object-curly-spacingjscs: [disallowSpacesInsideObjectBrackets](http://jscs.info/rule/
// bad
const foo = {clark: 'kent'};
// good
const foo = { clark: 'kent' };
- 19.12 Evite linhas com mais de 100 caracteres (incluindo espaços em branco). eslint:
max-lenjscs:maximumLineLength
Por quê? Isso garante legibilidade e manutenibilidade.
// 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.'));
Vírgulas (Commas)
- 20.1 Vírgulas iniciais (Leading commas): Não. 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 Vírgula final adicional (Additional trailing comma): Sim. eslint:
comma-danglejscs:requireTrailingComma
Por quê? Isso leva a diffs do git mais limpos. Além disso, transpilers como Babel removerão a vírgula final adicional no código transpilado, o que significa que você não precisa se preocupar com o problema da vírgula final em navegadores legados.
// 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',
];
Ponto e Vírgula (Semicolons)
- 21.1 Sim. 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;
}());
Conversão de Tipos e Coerção (Type Casting & Coercion)
// => this.reviewScore = 9;
// bad
const totalScore = this.reviewScore + '';
// good
const totalScore = String(this.reviewScore);
- 22.3 Números: Use
Numberpara o casting de tipo eparseIntsempre com uma base para analisar strings. eslint:radix
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 Se por algum motivo você estiver fazendo algo louco e
parseIntfor seu gargalo e você precisar usar Bitshift por razões de desempenho, deixe um comentário explicando por que e o que você está fazendo.
// 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 Nota: Tenha cuidado ao usar operações de bitshift. Números são representados como valores de 64 bits, mas as operações de bitshift sempre retornam um inteiro de 32 bits (fonte). O bitshift pode levar a um comportamento inesperado para valores inteiros maiores que 32 bits. Discussão. O maior inteiro com sinal de 32 bits é 2.147.483.647:
2147483647 >> 0 //=> 2147483647
2147483648 >> 0 //=> -2147483648
2147483649 >> 0 //=> -2147483647
- 22.6 Booleanos:
const age = 0;
// bad
const hasAge = new Boolean(age);
// good
const hasAge = Boolean(age);
// good
const hasAge = !!age;
Convenções de Nomenclatura (Naming Conventions)
- 23.1 Evite nomes de uma letra. Seja descritivo com sua nomenclatura.
// bad
function q() {
// ...stuff...
}
// good
function query() {
// ..stuff..
}
- 23.2 Use camelCase ao nomear objetos, funções e instâncias. eslint:
camelcasejscs:requireCamelCaseOrUpperCaseIdentifiers
// bad
const OBJEcttsssss = {};
const this_is_my_object = {};
function c() {}
// good
const thisIsMyObject = {};
function thisIsMyFunction() {}
- 23.3 Use PascalCase apenas ao nomear construtores ou classes. 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 Use um sublinhado
_à esquerda ao nomear propriedades privadas. eslint:no-underscore-danglejscs:disallowDanglingUnderscores
// bad
this.__firstName__ = 'Panda';
this.firstName_ = 'Panda';
// good
this._firstName = 'Panda';
- 23.5 Não armazene referências a
this. Use arrow functions ou 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 Se seu arquivo exporta uma única classe, o nome do arquivo deve ser exatamente igual ao nome da classe.
// 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 Use camelCase quando você exportar uma função padrão. O nome do arquivo deve ser idêntico ao nome da função.
function makeStyleGuide() {
}
export default makeStyleGuide;
- 23.8 Use PascalCase quando você exportar um singleton / biblioteca de funções / objeto vazio.
const AirbnbStyleGuide = {
es6: {
}
};
export default AirbnbStyleGuide;
Acessadores (Accessors)
- 24.1 Funções de acesso para propriedades não são obrigatórias.
- 24.2 Não use getters/setters JavaScript, pois causam efeitos colaterais inesperados e são difíceis de testar, manter e raciocinar. Em vez disso, se você criar funções de acesso, use getVal() e setVal(‘hello’).
// bad
dragon.age();
// good
dragon.getAge();
// bad
dragon.age(25);
// good
dragon.setAge(25);
- 24.3 Se a propriedade for um booleano, use
isVal()ouhasVal().
// bad
if (!dragon.age()) {
return false;
}
// good
if (!dragon.hasAge()) {
return false;
}
- 24.4 Tudo bem criar funções get() e set(), mas seja consistente.
class Jedi {
constructor(options = {}) {
const lightsaber = options.lightsaber || 'blue';
this.set('lightsaber', lightsaber);
}
set(key, val) {
this[key] = val;
}
get(key) {
return this[key];
}
}
Eventos (Events)
- 25.1 Ao anexar payloads de dados a eventos (sejam eventos DOM ou algo mais proprietário como eventos Backbone), passe um hash em vez de um valor bruto. Isso permite que um colaborador subsequente adicione mais dados ao payload do evento sem encontrar e atualizar todos os manipuladores para o evento. Por exemplo, em vez de:
// bad
$(this).trigger('listingUpdated', listing.id);
...
$(this).on('listingUpdated', (e, listingId) => {
// do something with listingId
});
prefira:
// good
$(this).trigger('listingUpdated', { listingId: listing.id });
...
$(this).on('listingUpdated', (e, data) => {
// do something with data.listingId
});
jQuery
- 26.1 Prefixe objetos jQuery com
$. jscs:requireDollarBeforejQueryAssignment
// bad
const sidebar = $('.sidebar');
// good
const $sidebar = $('.sidebar');
// good
const $sidebarBtn = $('.sidebar-btn');
- 26.2 Armazene em cache as pesquisas do 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 Para consultas DOM, use Cascading
$('.sidebar ul')ou parent > child$('.sidebar > ul'). jsPerf - 26.4 Use
findcom consultas de objeto jQuery com escopo.
// bad
$('ul', '.sidebar').hide();
// bad
$('.sidebar').find('ul').hide();
// good
$('.sidebar ul').hide();
// good
$('.sidebar > ul').hide();
// good
$sidebar.find('ul').hide();
Compatibilidade ECMAScript 5 (ECMAScript 5 Compatibility)
- 27.1 Consulte a tabela de compatibilidade do ES5 de Kangax.
Estilos ECMAScript 6 (ECMAScript 6 Styles)
- 28.1 Esta é uma coleção de links para os vários recursos do ES6.
- Arrow Functions
- Classes
- Object Shorthand
- Object Concise
- Computed Object Properties
- Template Strings
- Destructuring
- Default Parameters
- Rest
- Array Spreads
- Let and Const
- Iterators and Generators
- Modules
Biblioteca Padrão (Standard Library)
A Biblioteca Padrão contém alguns utilitários que estão quebrados, mas continuam lá por motivos de legado.
- 29.1 Use
Number.isNaNem vez deisNaN.
Por quê?
isNaNcoage valores não numéricos para números, retornando true para qualquer coisa que se converta para NaN. Se este comportamento for desejado, torne-o explícito.
// 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 Use
Number.isFiniteem vez deisFinite.
Por quê?
isFinitecoage valores não numéricos para números, retornando true para qualquer coisa que se converta para um número finito. Se este comportamento for desejado, torne-o explícito.
// bad
isFinite('2e3'); // true
// good
Number.isFinite('2e3'); // false
Number.isFinite(parseInt('2e3', 10)); // true
Testes (Testing)
- 30.1 Sim.
function foo() {
return true;
}
- 30.2 Não, sério:
- Não importa qual framework de teste você usa, você deve escrever testes!
- Tente escrever muitas funções puras pequenas e minimize onde as mutações ocorrem.
- Tenha cuidado com stubs e mocks - eles podem tornar seus testes mais frágeis.
- Nós usamos principalmente
mochano Airbnb.tapetambém é usado ocasionalmente para módulos pequenos e separados. - 100% de cobertura de teste é um bom objetivo para se esforçar, mesmo que nem sempre seja prático alcançá-lo.
- Sempre que você corrigir um bug, escreva um teste de regressão. Um bug corrigido sem um teste de regressão certamente quebrará novamente no futuro.
Desempenho (Performance)
- 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…
Recursos (Resources)
Aprenda ES6
- Draft ECMA 2015 (ES6) Spec
- ExploringJS
- ES6 Compatibility Table
- Comprehensive Overview of ES6 Features
Leitura Obrigatória
Ferramentas
- Code Style Linters
Outros Guias de Estilo
- Google JavaScript Style Guide
- jQuery Core Style Guidelines
- Principles of Writing Consistent, Idiomatic JavaScript
Outros Estilos
- 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
Leitura Adicional
- 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
Livros
- 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
In the Wild
Esta é uma lista de organizações que estão usando este guia de estilo. Envie-nos um pull request ou uma issue, e nós adicionaremos você à lista.
- 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
Tradução (Translation)
Este guia de estilo também está disponível em outras línguas:
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
Vietnamese: f1remoon/javascript-style-guide
O Guia do Guia de Estilo JavaScript (The JavaScript Style Guide Guide)
Converse conosco sobre JavaScript
- Encontre-nos no gitter.
Contribuidores (Contributors)
Licença (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.
Emendas (Amendments)
Nós encorajamos você a fazer um fork deste guia e alterar as regras para se adequar ao guia de estilo da sua equipe. Abaixo, você pode listar algumas emendas ao guia de estilo. Isso permite que você atualize periodicamente seu guia de estilo sem ter que lidar com conflitos de merge (merge conflicts).