Skip to content

Latest commit

 

History

History
1105 lines (811 loc) · 20.1 KB

Javascript.md

File metadata and controls

1105 lines (811 loc) · 20.1 KB

focusnetworks();

Focusnetworks JavaScript code styleguide.

Menu

Disclaimer

Esse documento foi inspirado por jQuery Style Guide, idiomatic.js e Airbnb JavaScript Style Guide.

⬆ voltar ao menu

Ponto e vírgulaa

  • Sempre, por favor! ASI é muito complicado, não confie nele.
// Bad
(function() {
  var name = 'John'
  return name
})()

// Good
(function() {
  var name = 'John';
  return name;
})();

⬆ voltar ao menu

Strict mode

  • Você pode usar o strict mode. Basta estar atento para não usá-lo em modo global!
// Bad
'use strict';

function doSomething() {
}

function doSomethingElse() {
}

// Good
function doSomething() {
  'use strict';
  // stuff
}

// Good
(function() {
  'use strict';

  function doSomething() {
  }

  function doSomethingElse() {
  }
})();

⬆ voltar ao menu

Context e closures

  • Sempre envolva seus módulos em closures (fechamentos) criando um contexto (context) único de execução. Jogar coisas no escopo global pode levar a todos os tipos de comportamentos estranhos.
// Bad
function doAwesomeStuff() {
  $('.js-item').fadeIn();
}

function doEvenCoolerStuff() {
  $('.js-item').animate({top: 100}, 'fast');
}

// Good
(function($) {
  function doAwesomeStuff() {
    $('.js-item').fadeIn();
  }

  function doEvenCoolerStuff() {
    $('.js-item').animate({top: 100}, 'fast');
  }
})(jQuery);

// Good
var Module = (function() {
  function Module() {
    // magic happens here
  }

  return Module;
})();

⬆ voltar ao menu

Variáveis

Definição de var simples

  • Use var simples na definição de variáveis.
// Bad
var foo = 'Foo';
var bar = 'Bar';
var baz = 'Baz';

// Good
var foo = 'Foo',
    bar = 'Bar',
    baz = 'Baz';

Ordem

  • Variáveis sem valor de inicialização deve vir em primeiro lugar.
// Bad
var name = 'John',
    surname = 'Doe',
    country,
    age = 42,
    email;

// Good
var country,
    email,
    name = 'John',
    surname = 'Doe',
    age = 42;

Estilo

  • Não siga o estilo "comma first"!
// Bad (OMG, really bad!)
var once
  , upon
  , aTime;

// Good
var once,
    upon,
    aTime;

// Bad
var user = {
  name: 'John'
  , surname: 'Doe'
  , age: 42
};

// Good
var user = {
  name: 'John',
  surname: 'Doe',
  age: 42
};

⬆ voltar ao menu

Objetos

Sintaxe literal de objetos

  • Use a sintaxe literal para criar objetos.
// Bad
var foo = new Object();

// Good
var bar = {};

Palavras reservadas

  • Evite usar palavras reservadas como chaves. Elas podem causar problemas em versões mais antigas do IE se não estiverem dentro de aspas.
// Bad
var foo = {
  class: 'Foo'
};

// Good
var bar = {
  klass: 'Bar'
};

// Good
var baz = {
  type: 'Baz'
};

Chaves de objeto

  • Use 🐫 camelCase ao nomear chaves de objetos, sempre quando possível.
// Bad
var user = {
  'name': 'John',
  'has-children': false,
  'is-underage': false,
  'age': 42
};

// Good
var user = {
  name: 'John',
  hasChildren: false,
  isUnderage: false,
  age: 42
};
  • Se você precisar usar aspas para envolver suas chaves, por qualquer motivo, use-o de maneira consistente:
// Bad
var config = {
  development: true,
  'markdown-plugin': true,
  shouldIgnoreManifest: false,
  PersistData: true,
  enforcenamespace: true
};

// Good
var config = {
  'development': true,
  'markdown-plugin': true,
  'should-ignore-manifest': false,
  'persist-data': true,
  'enforce-namespace': true
};

// Good
var config = {
  development: true,
  markdownPlugin: true,
  shouldIgnoreManifest: false,
  persistData: true,
  enforceNamespace: true
};

⬆ voltar ao menu

Arrays

Sintaxe literal de arrays

  • Use sintaxe literal para criação de arrays.
// Bad
var foo = new Array();

// Good
var bar = [1, 2, 3];

Adicionando itens

  • Se você não sabe a quantidade de itens do array use Array.push.
var groceries = [];

// Bad
groceries[groceries.length] = 'tomato';

// Good
groceries.push('oreo');

Limpando array

  • Para limpar um array, defina a quantidade como zero.
// Bad
var foo = [1, 3, 5];
foo = null;

// Good
var bar = [2, 4, 6];
bar.length = 0;

Conversão de array

  • Para converter um objeto de matriz semelhante a uma matriz, use Array.slice.
  • Você pode querer fazer isso porque objetos array-like (por exemplo, {'0': 'Olá', '1': 'lá'}) não têm métodos como .join(), para mais informações nesse assunto leia esse artigo
function argsToArray() {
  var args = Array.prototype.slice.call(arguments);
}

⬆ voltar ao menu

Strings

Aspas

  • Use aspas simples '' para strings.
// Bad
var morada = "Márcio Moradei";

// Good
var danilo = 'Danilo Vaz';

Concatenação

  • Concatene strings utilizando o operador mais +.
var name = 'Danilo';

// Bad
name.concat('Vaz');

// Good
name += ' Vaz';

Long strings

  • Prefira concatenação de long strings, sempre adicionando quebras de linha depois de um operador. Long strings podem afetar o desempenho (referências e discussão).
// Bad
var 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
var 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
var 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.';

Conversão de strings

  • Para converter objetos em strings, use o método toString().

  • A conversão com toString() não funciona com valores null e undefined. Para converter qualquer valor para string, concatene esse valor com uma string vazia. Isso é útil quando você não se importa com o valor da conversão (ex: em um logging ou tracking system). No caso de você converter um valor null, ele será transformado em um "null". A mesma regra é aplicada para valores undefined.

var value = 42;

// Good
value += '';

var empty;

empty += ''; // "undefined"

⬆ voltar ao menu

Funções

Argumentos de funções

  • Sempre que você tem mais de 3 argumentos sendo passados para uma função, é preferível você usar um objeto em seu lugar.
// Bad

// Muitos argumentos
function setUser(firstName, lastName, age, gender, occupation) {
  // faz alguma coisa
}

setUser('Jon', 'Snow', 25, 'Male', 'Nights-watcher');

// Good

// Ao invés disso, use uma config/opções de objetos
function setUser(user) {
  // faz alguma coisa
}

setUser({
  firstName: 'Jon',
  lastName: 'Snow',
  age: 25,
  gender: 'Male',
  occupation: 'Nights-watcher'
});

Convenções de nomenclatura

  • Use camelCase quando nomear objetos, funções e instancias.
// bad
var foo_bar = 'I am messed up';

// good
var fooBar = 'I am alright!';
  • Use PascalCase quando nomear construtores e "classes".
// Bad
function crewMember(name, role) {
  this.name = name;
  this.role = role;
}

var danilo = new crewMember('Danilo', 'Desenvolvedor');

// Good
function CrewMember(name, role) {
  this.name = name;
  this.role = role;
}

var alan = new CrewMember('Alan', 'Designer');

Nomenclatura de funções

  • Evite nomes com uma única letra. Seja descritivo e claro.
// Bad
function f() {
  // What the hell is this?
}

// Good
function bootstrapFoo() {
  // Ah, ok!
}

// Bad
function stuff() {
  // "stuff" is too generic
}

// Good
function doAnimationStuff() {
  // Now we're talking
}

Nomenclatura de construtores

  • Sempre envolva as invocações de construtores entre brackets. Será mais fácil de passar novos valores no futuro.
// Bad
var foo = new FooBar;

// Good
var bar = new FooBar();
var baz = new FooBar(1, 'lorem');

Nomenclatura de propriedades privadas

  • Utilize sempre um sublinhado inicial _ ao nomear propriedades privadas e métodos.
// Bad
var $name = 'Foo';
var __name = 'Bar';

// Good
var _name = 'Baz';

Referenciando this

  • Quando fizer um referência ao this nomei-o com self.
// Bad
function() {
  var that = this;

  return function() {
    console.log(that);
  }
}

// Bad
function() {
  var _this = this;

  return function() {
    console.log(this);
  }
}

// Good
function() {
  var self = this;

  return function() {
    console.log(self);
  }
}

Nomenclatura de booleanos

  • Quando nomear variáveis booleanas, deve começar com "is", "has", "should" ou "was".
// Bad
var ready = true,
    animate = true,
    started = false,
    animation = true;

// Good
var isReady = true,
    shouldAnimate = true,
    wasStarted = true,
    hasAnimation = true;
  • Quando nomear funções booleanas, deve começar com "is".
// Bad
function ready() {
  return false;
}

// Good
function isReady() {
  return true;
}

Nomenclatura de acessores

  • Quando nomear um acessor, tente começar com "get" or "set". Também nomeie explicitamente value como parâmetro getters.
var currentStatus;

// Bad
function status(val) {
  if (val) {
    currentStatus = val;
  }

  return currentStatus;
}

// Good
function setStatus(value) {
  currentStatus = value;
}

function getStatus() {
  return currentStatus;
}

Nomenclatura de event handlers

  • Quando nomear um event handler (manipulador de evento), combine sua ação com o tipo de evento.
// Bad
$('.button').click(click);

function click() {
  console.log('meh');
}

// Good
$('.button').click(toggleColorOnClick);

function toggleColorOnClick() {
  console.log('should toggle color on click!');
}

Nomenclatura de seletores de elemento

  • Ao nomear seletores de elementos nas classes DOM que terá qualquer tipo de comportamento, adicione o prefixo js para o nome do seu componente separando palavras usando um hífen -.
<ul class="js-navigation-menu">
  <li>Foo</li>
  <li>Bar</li>
</ul>
var menu = $('.js-navigation-menu');

⬆ voltar ao menu

Propriedades

  • Use o . para acessar as propriedades.
var user = {
  name: 'John',
  age: 42
};

// Bad
var userName = user['name'];

// Good
var userAge = user.age;
  • Use colchetes [] para acessar propriedades dinâmicas.
var user = {
  name: 'John',
  age: 42
};

function getUserInfo(info) {
  return user[info];
}

var userName = getUserInfo('name');

⬆ voltar ao menu

Expressões condicionais e de igualdade

  • Use === e !== ao invés de == e !=.

⬆ voltar ao menu

Blocos

  • Sempre envolva blocos dentro de chaves e use novas linhas.
// Bad
if (false)
  return;

// Bad
if (false) { return false; }

// Good
if (true) {
  return true;
}

// Good
if (true) {
  return true;
} else {
  return false;
}

⬆ voltar ao menu

Comentários

  • Não faça comentários insignificantes e óbvios, seja conciso sobre ele.

  • Sinta-se livre para utilizar sintaxe markdown nos comentários.

  • Não há necessidade de usar a sintaxe JSDoc uma vez que não geramos a documentação automaticamente.

  • Usando tags FIXME, TODO e NOTE poderá ajudar outros desenvolvedores a entender e manter seu código. Você pode usar isso como quiser.

  • Utilize sintaxe de bloco de documentação seguido por uma nova linha de comentários de várias linhas. Existem ferramentas disponíveis para tornar isso realmente fácil.

// Bad

// Usado para casar um `RegExp` de caracteres especiais.
// Veja esse [artigo sobre caracteres `RegExp`](http://www.regular-expressions.info/characters.html#special)
// para mais detalhes.

var matchSpecialChars = /[.*+?^${}()|[\]\/\\]/g;

// Bad

/*
Usado para casar um `RegExp` de caracteres especiais.
Veja esse [artigo sobre caracteres `RegExp`](http://www.regular-expressions.info/characters.html#special)
para mais detalhes.
*/

var matchSpecialChars = /[.*+?^${}()|[\]\/\\]/g;

// Good

/**
* Usado para casar um `RegExp` de caracteres especiais.
* Veja esse [artigo sobre caracteres `RegExp`](http://www.regular-expressions.info/characters.html#special)
* para mais detalhes.
*/

var matchSpecialChars = /[.*+?^${}()|[\]\/\\]/g;
  • Use // para comentários de linha única. Coloque comentários de linha única sobre uma nova linha acima do assunto do comentário e adicione uma linha em branco antes do comentário.
// Bad
var active = true;  // is current tab

// Good
// is current tab
var active = true;

// Bad
function getType() {
  console.log('fetching type...');
  // set the default type to 'no type'
  var type = this._type || 'no type';

  return type;
}

// Good
function getType() {
  console.log('fetching type...');

  // set the default type to 'no type'
  var type = this._type || 'no type';

  return type;
}

⬆ voltar ao menu

Espaços em branco

Tabs

  • Use soft tabs definido para 2 espaços e nunca misture espaços com tabs.
// Bad
function() {
∙∙∙∙var name;
}

// Bad
function() {
∙var name;
}

// Bad
function() {
⇥var name;
}

// Good
function() {
∙∙var name;
}

EOF

  • Sempre adicione uma linha em branco ao final do seu documento.
// Bad
(function() {
  document.write('Hello World!');
})();

// Good
(function() {
  document.write('Hello World!');
})();

Declaração de condições e loop

  • Coloque 1 espaço antes e depois de uma declaração de condição ou loop.
// Bad
if(false){return false;}

// Good
if (true) {
  return true;
}

// Bad
while(false){console.log('whatever');}

// Good
while (false) {
  console.log('alright!');
}

Operadores

  • Separe os operadores com espaços.
// Bad
var x=y+5;

// Good
var x = y + 5;

Etapas de loop

  • Coloque 1 espaço depois das etapas do loop e argumentos de função.
// Bad
for(var i=0;i<10;++i) {
  console.log(i);
}

// Good
for (var i = 0; i < 42; ++i) {
  console.log(i);
}

// Bad
function setUser(name,surname,age){
  // sets user
}

// Good
function setUser(name, surname, age) {
  // sets user
}

Declaração de objetos

  • Em objetos que têm mais do que uma única propriedade você deve quebrar todas as propriedades em novas linhas.
// Bad
var user = {name: 'John', surname: 'Doe', age: 42};

// Good
var user = {
  name: 'John',
  surname: 'Doe',
  age: 42
};
  • Adicionar espaços internos quando declarar objetos embutidos.
// Bad
var app = {locale: 'pt-br'};

// Good
var app = { locale: 'pt-br' };

Encadeamento

  • Use identação quando fizer longos encadeamentos de método.
// Bad
$('#items').find('.selected').highlight().end().find('.open').updateCount();

// Good
$('#items')
  .find('.selected')
    .highlight()
    .end()
  .find('.open')
    .updateCount();

⬆ voltar ao menu

Verificação de tipo

String

typeof variable === 'string';

Número

typeof variable === 'number';

Booleano

typeof variable === 'boolean';

Objeto

typeof variable === 'object';

Array

Array.isArray(arrayLikeObject);

Node

elem.nodeType === 1;

null

variable === null;

null ou undefined

variable == null;

undefined

Variável global

typeof variable === 'undefined';

Variável local

variable === undefined;

Propriedade

object.prop === undefined;
object.hasOwnProperty(prop);
'prop' in object;

⬆ voltar ao menu

Melhores práticas

  • Não comece fechamentos com ponto e vírgula.

  • Nós encorajamos você a registrar eventos da aplicação e mudanças importantes apenas no modo de desenvolvimento. Siga o formato de Module/ClassName :: method() :: message.

function App() {
  console.log('App :: App instance created');
}

App.prototype.bootstrap = function() {
  console.log('App :: bootstrap() :: App was initialized');
};

jQuery

  • Cacheie consultas de jQuery sempre que possível.
  • Prefira remove() ao invés de empty().

⬆ voltar ao menu

Links

Artigos e posts

Ferramentas

⬅ voltar à página inicial    ⬆ voltar ao menu