#1: Constantes

Se você já programou uma linguagem funcional ou qualquer outra que suporta constantes, a noção de imutável não deve ser alienígena para você. Uma “variável” que não faz jus ao nome variável porque, bem, uma vez determinado, seu valor não poderá ser alterado. Inspirado mais uma vez na matemática, o mundo da programação usa constantes.

A vantagem de usar constantes? Código imutável é mais fácil de acompanhar. É mais inteligente você mudar as coisas de nome quando elas passam a ser outras coisas. Isso também evita que atribuições acidentais quebrem o fluxo condicional:

Atribuição acidental dentro de um predicado

Embora uma comparação seja feita com os operadores == ou === , um dia você vai estar digitando rápido, ou pensando em outra coisa, e escrever = em vez disso. Não negue: provavelmente já aconteceu!

Outra vantagem de const é puramente semântica: indicar para os outros programadores que aquele valor não deve ser alterado — algo como marcar seu território para ninguém invadir.

#2: for…of

Loops ao estilo C/C++ já cansaram. Não me lembro da última vez que escrevi isso:

Veeelho.

Além de propenso a erros, de exigir uma variável mutável e de você precisar determinar a condição de break, você ainda arrisca que algum desses valores seja alterado (por um lapso cerebral do programador), causando um loop que quebre antes do fim ou pior: um loop infinito, que mesmo com todas as melhorias de performance e multiprocesso entre abas ainda pode travar sua janela inteira do Chrome.

Se eu quero tomar uma ação para cada valor de um Array, é muito mais limpo fazer isso:

Whew!

Dentro deste bloco, item será cada item de myList . Não preciso nem trabalhar com o índice: nada de myList[i] ou algo parecido.

#3: Shorthand objects

Você tem algumas variáveis que extraiu de vários lugares: algumas vieram de elementos do DOM, outras de uma resposta da API, e mais uma de um cálculo. Você precisa enviar todas elas através de uma outra requisição AJAX. Você vai em frente e cria o seguinte objeto:

WET

OK… você precisou repetir todos os identificadores. Isso foi mesmo necessário?

Vamos experimentar:

Mágica DRY!

Quando o valor de uma propriedade num object literal é igual à variável com o mesmo identificador (um nome igual), não precisamos escrever propriedade: propriedade, , mas apenas propriedade, .

Legal, né?

#4: Lazy getters e setters

Muitos objetos têm valores que precisam ser recalculados a partir de outras propriedades. Embora eu não seja um fã de programação orientada a objetos, às vezes é melhor usá-la quando o ambiente exige do que lutar contra um padrão estabelecido.

Em linguagens como C++ e Java, há o costume de usar getters e setters para atribuir valores, assim, caso alguma operação (um cálculo ou transformação) precise ser feita sobre o valor antes de salvá-lo ou exibi-lo, podemos apenas alterar a função. Em JavaScript, bem como em Python e Ruby, isso não se faz necessário:

Observe a definição de childrenPerYear

Ao usar a sintaxe get methodName () , criamos um lazy getter, um método interno que recalcula o valor de uma propriedade toda vez que ela é acessada. Assim, no nosso exemplo, não precisamos criar getChildrenPerYear e muito menos setAge e setChildren .

Também podemos criar setters, funções que são executadas ao atribuir uma propriedade usando o operador = .

Observe como lastChange é atualizado a cada set em bar.

#5: Splat

Já precisou criar um objeto a partir de outro? É um saco digitar tudo de novo desse jeito:

Bleh.

Vamos, então, à alternativa:

Viva o splat!

Graças ao splat operator, esses três pontinhos, podemos “roubar” todas as propriedades de john (inclusive getters e setters) e inseri-las no novo objeto.

Também funciona com arrays:

Bem mais fácil que concat!

#6: Desestruturação

Você com certeza já precisou extrair propriedades de objetos ou arrays. O exemplo mais palpável que consigo imaginar é uma resposta JSON de uma API. Vem tudo dentro de um objeto, que normalmente a gente chama de response ou de data . Aí temos situações como essas:

Já que estamos extraindo todos os valores de uma única variável, que tal fazermos a atribuição uma única vez? Eis a desestruturação de objetos:

Desestruturação em ação

Como você pode observar, podemos usar a mesma sintaxe de object literals para atribuir valores a variáveis. Neste exemplo, criamos name , age e nom a partir das propriedades name , age e nameInFrench do objeto data .

Também funciona com arrays:

#7: Operador de resto

O nome traduzido é péssimo, mas o rest operator é um recurso muito útil. Antigamente, caso quiséssemos usar uma quantidade indeterminada de argumentos, acessaríamos o objeto arguments de uma função tradicional, declarada com function :

No entanto, isso não é possível através de uma arrow function, que não pode ser usada como construtor e, portanto, não tem escopo próprio. Outro problema é que arguments sempre vai conter todos os argumentos da função, mesmo que alguns tenham sido declarados:

Acontece que tanto em funções tradicionais como em arrows, temos acesso ao operador de resto:

Ele praticamente elimina a necessidade de arguments .

#8: Uma arrow function sem bloco retorna a expressão após a flecha

Isso é especialmente interessante quando estamos usando funções como lambdas.

Sem chaves!

Aqui não precisamos usar return . Na falta de um bloco {} , o interpretador entende que o valor de retorno é a expressão à frente da seta.

#9: Nós temos conjuntos!

Em vez de rodar um filter checando duplicatas em um array ou postar em grupos reclamando que JavaScript não possui o uniq do Ruby, saiba que, assim como Python, JavaScript moderninho possui conjuntos ( sets em inglês). Inspirados pelo conceito matemático de conjunto, os sets são listas de elementos que não se repetem. Observe:

E os sets herdam de Iterable e possuem uma API excelente.

#10: Você pode definir classes “clássicas”

E elas vão funcionar como classes JavaScript tradicionais, permitindo que o Babel efetue conversões eficientes e precisas.

Bem melhor que usar prototype, não é?

Bônus: pare de usar ponto-e-vírgula!

Qualquer interpretador JavaScript — e não só os modernos, mas realmente qualquer um — entende que uma declaração ou expressão termina quando a sintaxe para de fazer sentido e há pelo menos uma quebra de linha entre os termos.

Isso significa que o ponto-e-vírgula é completamente desnecessário a não ser que a segunda linha se pareça uma continuação da primeira. E acaba que a única maneira de eu acidentalmente continuar uma linha abaixo de outra — reforço, acidentalmente — é com parênteses ou colchetes. Exemplo onde pode haver um engano:

Aqui, o interpretador entende que tentamos chamar a string ‘test’ como uma função

Para não obrigar todas as linhas a terminar com ; sem necessidade, o guia StandardJS sugere que iniciemos as linhas que comecem com arrays ou expressões fechadas com parêntese com ponto-e-vírgula. Assim, o problema é resolvido: