JS nosso de cada dia

Blasfêmias a parte, esse post não é sobre a semelhança do nosso querido Jaydson com o carpinteiro de Jerusalém. jaydson-jc


Jaydson Gomes no FrontInSampa 2013

A ideia desse post é mostrar como algumas features relativamente recentes de JS podem facilitar em algumas tarefinhas mundanas do nosso dia a dia, tornar nosso código mais legível e, talvez, até mais divertido de escrever.

Selecionar elementos no DOM

O seletor do jQuery ($(element))salvou muita gente de trabalhos muito penosos e chatos, mas em ES5 já começamos a ter opções nativas que davam conta do recado satisfatoriamente: document.querySelector(element) e document.querySelectorAll()

ProTip: substituindo o document por outro elemento restringe o scope da tua interação. 😉

No entanto, querySelectorAll não retorna um array com todos os elementos, e sim uma nodeList. Uma nodeList anda, se mexe, alimenta e se parece com um array,mas não é. Então todos os métodos que tu gostaria de usar nessa lista de elementos não funcionam. Em ES5, já tínhamos uma maneira de lidar com isso: Array.slice.call(document.querySelectorAll('div'))

Agora sim temos um array com todas as div do nosso documento. Isso já resolve nosso problema, mas em ES2015 temos um novo método que torna esse snippet difícil de lembrar e chato de ler em algo muito mais simples e intuitivo:

Array.from(document.querySelectorAll('div'))

Array.from() na MDN

Bem melhor, não? E o suporte nativo já chegou em todas versões recentes dos principais browsers. Pode testar aí!

Checar presença de valor/elemento

'schnitzel'.indexOf('z') > -1
[1,2,3,4,5].indexOf(4) > -1 

Coisa linda essa pattern, né? Todo mundo escreveu algo desse tipo pelo menos uma vez, pedimos o índice de determinado caracter ou elemento e, caso ele não esteja presente, o valor desse índice é -1. Enfim, sempre me pareceu meio hacky, mas funciona e quebra bem o galho. Só que agora não precisamos mais dele pra isso:

'schnitzel'.includes('z') //true
[1,2,3,4,5].includes(4) //true

Bem melhor, não?! Podemos deixar .indexOf pra quando ele realmente funciona.

Array.includes() na MDN

Mas tem mais, includes trouxe também 2 métodos parecidos:

'schnitzel'.startsWith('s') //true
[1,2,3,4,5].endsWith(5) //true

String.startsWith() na MDNString.endsWith() na MDN

Mas calma! Ainda não acabei com indexOf.

Abre o console e cola esse snippet:

[1, NaN].indexOf(NaN)

Não parece certo, né?

Não vamos entrar no mérito dos “porquês” e “como”, mas indexOf não serve pra NaN e, para isso, temos o findIndex() agora. O funcionamento é um pouco diferente, temos uma função anônima que serve como filtro e uma vez que esta retorne true, findIndex te passa o índice do elemento em questão.

[1, NaN].findIndex( e => { return Number.isNaN(e) })

Agora sim.

Array.findIndex() na MDN

Juntar Arrays

Considere os seguintes arrays:

let mammals = ['cat', 'dog'],
    birds = ['parrot', 'pigeon'],
    rodents = ['hamster', 'guinea pig'];

Até então, usávamos .concat:

let pets = mammals.concat(birds, rodents);

O que pode parecer bom o suficiente, mas na minha opinião prejudica a manutenção e legibilidade do código. Chamar o método a partir de mammals sugere que este é mais importante que os outros dois arrays. Enfim, pode ser frescura, mas eu prefiro usar spread até mesmo pra isso:

let pets = [...mammals, ...birds, ...rodents];

Spread operator na MDN

Default parameter

Quem nunca:

function foo(parameter) {
  parameter || (parameter = 'defaultValue');
  //...
}

Com default parameter fica tudo mais simples e fácil:

function foo(parameter = 'defaultValue') {
  //...
}

Default Parameters na MDN


Vou parar por aqui, mas existem muito mais métodos e features de ES2015 que podem facilitar imensamente nossa vida no dia a dia. Aliás, deixa no comentário ou me dá um grito no twitter se tem alguma que tu acha que eu devia ter citado aqui!

E, claro, qualquer outro feedback também é muito bem-vindo! 😉


BrazilJS é uma iniciativa NASC