Padrões de código JavaScript no WordPress

Em busca da produtividade e legibilidade do código presente nos temas a equipe do Core do WordPress escreveu uma seção para falar sobre padrões de codificação para plataforma. Esse é o segundo post da sobre o assunto no post anterior falei sobre padronização de código CSS, Nesse post vamos abordar padrões de escrita para JavaScript.

JavaScript tornou-se uma das principais linguagens da atualidade e é um item chave no desenvolvimento de temas e plugins no WordPress. Claro que padronizar seu código JavaScript é essencial para manter consistência no projeto. Todo código base deve parecer escrito por uma única pessoa.

O “WordPress JavaScript Coding Standards” foi uma adaptação do “jQuery JavaScript Style Guide”, o padrão do WordPress difere do jQuery nos seguintes pontos:

  • WordPress usa aspa simples para declaração de string.
  • Instruções de Case são indentadas para indicar as mudanças de blocos.
  • Conteúdo de funções são constantemente indentadas, incluindo os empacotadores de fechamento de todo o arquivo.
  • Algumas regras para espaço em branco são diferentes, para manter consistência com o “WordPress PHP coding standards”.
  • 100 caracteres são o limite para uma linha de código jQuery, mas no WordPress não são rigorosamente aplicadas.

Espaçamento

Uso de espaços livremente em todo seu código. “Em caso de dúvida, tire o espaço.”

Estas regras incentivam o uso de espaço para melhorar a legibilidade do código. O processo de minificação cria arquivos otimizados para os browsers lerem e processarem os arquivos, mas não para os programadores. O ideal é utilizar uma versão minificada para produção e uma versão sem minificação para desenvolvimento.

Além deste quesito temos as seguintes recomendações para espaçamento:

  • Crie indentação com tab.
  • Retire os espaços em branco no final da linha e em linhas em branco.
  • As linhas não devem ser longas, não exceder o limite já especificado de 100 caracteres(contando tabs e espaço). Esta é uma regra “soft”, mas linhas longas geralmente apontam código desorganizado.
  •  if / else / for while / try, os blocos devem sempre utilizar chaves e quebras de linhas, evite utilizar condicionais em uma única linha com chaves.
  • Os operadores de “unários”, exemplo, ++ ou — não devem ter espaço entre seu operando, exemplo “contador++”.
  • Qualquer “,” ou “;” não deve preceder de espaço
  • Qualquer “;” utilizado como sinalizador de um final de uma operação deve estar sempre  ao final da linha, ou seja evite “contador++; a = contador;” na mesma linha.
  • Qualquer “:” depois de um nome de uma propriedade em uma definição de um objeto, não deve ser precedido de espaço, exemplo “valor: 9”.
  • A “?” e “:” de uma condicional ternária deve ter espaço em ambos os lados
  • Não utilize espaço em declarações de tipos vazios, exemplo, {} [] ou fn().
  • Toda “!” utilizada como operador de negação deve conter um espaço em seguida.*
  • Indente todo conteúdo de uma função, mesmo que todo o arquivo esteja contido dentro da função.*
  • Espaços podem podem alinhar comentários ou espaços dentro de uma linha de código, mas somente o TAB pode alinhar o início de uma linha de código.*

Os itens marcados com um “*” ao final da linha fazem parte do WordPress JavaScript standards, sendo um complemento ao padrão do jQuery. Essas aplicações são recomendadas para manter coerência com os padrões de escrita do PHP.

Os espaços em branco são facilmente acumulados no final de cada linha, evite isso utilizando JSHint,  Outra maneira de evitar esses espaços é definindo cores para os espaços no estilo do seu editor.

Objetos

Declarações de objetos podem ser feitas em uma única linha, mas isso não é aconselhável lembrem das recomendações do tamanho da linha. O recomendado é deixar uma propriedade por linha. Nome de propriedades precisam somente de aspas quando possuem uma palavra reservada ou caracteres especiais:

// Recomendado
var map = {
    ready: 9,
    when: 4,
    'you are': 15
};

// Aceito somente para pequenos objetos
var map = { ready: 9, when: 4, 'you are': 15 };

// Não Recomendado
var map = { ready: 9,
    when: 4, 'you are': 15 };

Arrays e Chamadas de Funções

Sempre adicione espaços extras em torno dos elementos e argumentos:

array = [ a, b ];

foo( arg );

foo( 'string', object );

foo( options, object[ property ] );

foo( node, 'property', 2 );

Exceções

Para manter a consistência com o padrão PHP, não inclua um espaço em torno strings ou inteiros usados como keys de uma array:

prop = object['default'];
firstArrayElement = arr[0];

Função com callback, objetos ou array como um argumento único, sem espaço em ambos os lados do argumento:

foo(function() {
    // Faça algo
});

foo({
    a: 'alpha',
    b: 'beta'
});

foo([
    'alpha',
    'beta'
]);

Função com callback, objeto ou array no primeiro argumento passamos sem espaço o segundo argumento seguimos o padrão:

foo(function() {
    // Do stuff
}, options );

Essa regra se aplica caso a função/array/objeto for o último argumento, ela segue sem espaços e os primeiros itens seguem o padrão.

Um bom exemplo de uso de espaçamento:

var i;

if ( condition ) {
    doSomething( 'with a string' );
} else if ( otherCondition ) {
    otherThing({
        key: value,
        otherKey: otherValue
    });
} else {
    somethingElse( true );
}

Indentação e quebra de linhas

Indentação e quebra de linhas adicionam legibilidade para declarações complexas. Tabs devem ser usados sempre para indentação do conteúdo que estiver dentro das chaves, também usamos um tab para sinalizar o nível do conteúdo.

(function( $ ) {
    // Expressions indented

    function doSomething() {
        // Expressions indented
    }
})( jQuery );

Blocos

IF, ELSE, FOR, WHILE e TRY devem sempre utilizar chaves e estar organizado em multi-lines. A abertura da chave deve estar na mesma linha da definição da função/condicional/loop. A chave de fechamento deve estar na linha seguinte da última declaração do bloco.

Exemplo:

var a, b, c;

if ( myFunction() ) {
    // Expressions
} else if ( ( a && b ) || c ) {
    // Expressions
} else {
    // Expressions
}

Operações Multi-line

Quando uma operação é muito longa para uma única linha, utilizamos uma quebra de linha e tal deve ocorrer após um operador.

// Bad
var html = '<p>The sum of ' + a + ' and ' + b + ' plus ' + c
    + ' is ' + ( a + b + c );

// Good
var html = '<p>The sum of ' + a + ' and ' + b + ' plus ' + c +
    ' is ' + ( a + b + c );

Métodos encadeados

Quando é utilizado um método encadeado ele pode criar uma linha muito longa, o remendado é ter uma chamada por linha, se o método muda o contexto ele deve ser aplicado um nível extra de indentação.

elements
    .addClass( 'foo' )
    .children()
        .html( 'hello' )
    .end()
    .appendTo( 'body' );

Atribuições e variáveis Globais

Declarando variáveis com var

Cada variável deve começar com a declaração “var” e as variáveis separadas por virgula. Na quebra de linha utilize indentação como no exemplo a seguir:

// Good
var k, m, length,
    // Indent subsequent lines by one tab
    value = 'WordPress';

// Bad
var foo = true;
var bar = false;
var a;
var b;
var c;

Variáveis Globais

No passado do WordPress o seu core fazia uso pesado de variáveis globais. Algumas variáveis globais ficam disponíveis por necessidade de integração com os plugins e não devem ser removidas. Outra recomendação é que todas as variáveis globais devem ser documentadas.

Bibliotecas Comuns

Backbone, jQuery, Underscore, e o “wp global” são todos registrados como itens “globais permitidos” no root do arquivo .jshintrc.

Backbone e Underscore podem ser acessados diretamente a qualquer hora. jQuery deve ser acessado $ passando por jQuery como um objeto de uma função anônima:

(function( $ ) {
  // Expressions
})( jQuery );

Isso irá evitar a chamada do “.noConflict()”, ou definir que o $ seja usado com outra variável. Os arquivos que adicionam ou modificam, o “wp object” acessa com mais segurança os itens globais isso evita a substituição previa do set de propriedades:

/* no topo do arquivo defina wp caso não exista 
passe um objeto vazio para evitar problemas.*/
window.wp = window.wp || {};

Convenções de nomenclaturas

  • Variáveis e nomes de funções devem ser palavras completas, utilizando camel case com a primeira palavra em caixa baixa. Esta é uma área que difere dos padrões do PHP para WordPress.
  • Construtores que utilizam “new” devem ter a primeira letra maiúscula.
  • Os nomes das variáveis e construtores devem ser descritivos, mas não excessivamente.
  • Exceções são permitidas para “interators”, tais como o uso de “i” para indicar o indice de um loop.

Comentários

Comentários vem antes do código a qual se refere e deve sempre ser precedido de uma linha em branco. A primeira letra do comentário deve ser maiúscula e inclua frases completas que descrevam a operação, não tenha preguiça de incluir comentários, eles são importantes para manter a fluidez do desenvolvimento. Após “//” inclua um espaço.

someStatement();

// Descreva ao sobre a complexidade da linha seguinte
$( 'p' ).doSomething();

/*
Este é um exemplo de uma comentário multiline,
caso precise de mais de uma linha pra descrever o 
bloco seguinte
*/

//Comentários inline também são permitidos
function foo( types, selector, data, fn, /* INTERNAL */ one ) {
    // Do stuff
}

Igualdade

As verificações de igualdades estritas(===) deve ser utilizada no lugar da verificação de igualdade abstrata(==). Use somente (==) quando realmente deseja saber se o valor é null ou undefined.

Checando tipos

Para checagem de tipos utilize esse padrão:

  • String: typeof object === ‘string’
  • Number: typeof object === ‘number’
  • Boolean: typeof object === ‘boolean’
  • Object: typeof object === ‘object’ or _.isObject( object )
  • Plain Object: jQuery.isPlainObject( object )
  • Funções: _.isFunction( object) or jQuery.isFunction( object )
  • Array: _.isArray( object ) or jQuery.isArray( object )
  • Element: object.nodeType or _.isElement( object )
  • null: object === null
  • null or undefined: object == null
  • undefined:
    • Variáveis globais: typeof variable === ‘undefined’
    • Variáveis locais: variable === undefined
    • Propriedades: object.prop === undefined
    • Qualquer um dos anteriores: _.isUndefined( object )

Strings

Use aspas simples para string literais:

var myStr = 'strings should be contained in single quotes';

// para adicionar as simples dentro da string utilize contra-barra
var myStr2 = 'Note the backslash before the \'single quotes\'';

Switch

O uso de switch é geralmente desencorajado, mas pode ser útil para comparação de um grande números de casos, especialmente quando realizamos uma série de tratamentos e queremos incluir um tratamento para exceções com “default”.

Como usar o switch:

  • Use um “break” para cada “case” com exceção do “default”.
  • Indente o conteúdo dentro do case com um tab
switch ( event.keyCode ) {

    // ENTER E SPACE disparam a mesma função: x()
    case $.ui.keyCode.ENTER:
    case $.ui.keyCode.SPACE:
        x();
        break;
    case $.ui.keyCode.ESCAPE:
        y();
        break;
    default:
        z();
}

Não é recomendado utilizar o return dentro do case, defina os valores de saída e utilize o return após o switch, podemos ver uma aplicação no código abaixo:

function getKeyCode( keyCode ) {
    var result;

    switch ( event.keyCode ) {
        case $.ui.keyCode.ENTER:
        case $.ui.keyCode.SPACE:
            result = 'commit';
            break;
        case $.ui.keyCode.ESCAPE:
            result = 'exit';
            break;
        default:
            result = 'default';
    }

    return result;
}

Boas Práticas

Arrays

Crie arrays com [] no lugar de new Array().

var myArray = [];

//Você pode inicializar um array e já atribuir seus valores:
var myArray2 = [ 1, 'WordPress', 2, 'Blog' ];

Objetos

Existem várias formas para criar um objeto com JavaScript. Notação do objeto literal, “{}”, é considerado o mais performático e de fácil leitura.

var myObj = {};

A notação literal de um objeto deve ser usado a menos que o objeto trabalhe com prototype, neste caso utilizamos o “new”

var myObj = new ConstructorMethod();

As propriedades do objeto devem ser acessados via “.” a menos que a chave da propriedade use o nome de uma palavra reservada, uma string não válida ou venha através de uma variável.

prop = object.propertyName;
prop = object[ variableKey ];
prop = object['default'];
prop = object['key-with-hyphens'];

Condicionais “Yoda”

Para manter consistência com os padrões de código do PHP sempre compare com a variável no lado direito e a constante no lado esquerdo, essa regra vale para strings, booleanos, inteiros…

if ( true === myCondition ) {
    // Do stuff
}

Interações

Quando queremos varrer uma coleção utilizamos o “for”, é recomendado armazenar o valor máximo em uma variável em vez de recalcular o valor máximo em casa interação.

// Good & Efficient
var i, max;

// consultamos o valor máximo uma única vez
for ( i = 0, max = getItemCount(); i < max; i++ ) {
    // Do stuff
}

// Bad & Potentially Inefficient:
// getItemCount() consultamos o valor máximo a cada interação
for ( i = 0; i < getItemCount(); i++ ) {
    // Do stuff
}

Na documentação temos duas recomendações para underscore, jQuery e uma recomendação para o uso de JSHint. Esse itens eu prefiro tratá-los e um post separado a tradução desse artigo me ajudou bastante muitas recomendações desconhecia. Algumas recomendações tratam da parte visual do seu código um código organizado para mim é igual a uma boa caligrafia. Isso ajuda na legibilidade e claro uma padronização deixa o time bem entrosado.

O artigo original você confere aqui:

http://make.wordpress.org/core/handbook/coding-standards/javascript/

Os Padrões JavaScript coding do WordPress são baseados nos padrões do jQuery você pode conferir aqui:

http://contribute.jquery.org/style-guide/js/

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *