O post de hoje é uma tradução de um artigo que vi uns dias atrás, de autoria do Nick, e achei muito legal, por isso achei que seria interessante compartilhá-lo com vocês aqui no blog. Pra quem deita e rola no inglês, pode conferir o artigo original aqui. Para quem não tem uma boa afinidade com a língua, segue o artigo traduzido logo abaixo:
Estava lendo o MDN docs outro dia e descobri essas features e APIs JavaScript que eu nunca tinha ouvido falar. Então aqui está uma pequena lista dessas coisas, útil ou não – aprender JS parece uma coisa que nunca tem fim.
Label Statements
Você pode rotular blocos e loops for em javascript. Quem sabia? (Eu não!) Você pode pegar a referência à esses rótulos e usar break e continue nos loops for, e break em blocos.
loop1: // rotulando "loop1"
for (let i = 0; i < 3; i++) { // "loop1"
loop2: // rotulando "loop2"
for (let j = 0; j < 3; j++) { // "loop2"
if (i === 1) {
continue loop1; // continue no "loop1"
// break loop1; // sai do "loop1"
}
console.log(`i = ${i}, j = ${j}`);
}
}
/*
* # Output
* i = 0, j = 0
* i = 0, j = 1
* i = 0, j = 2
* i = 2, j = 0
* i = 2, j = 1
* i = 2, j = 2
*/
Aqui vai um exemplo nomeando um bloco, você pode usar apenas break em blocos.
foo: {
console.log('um');
break foo;
console.log('esse log não será executado');
}
console.log('dois');
/*
* # Output
* um
* dois
*/
Operador “void”
Eu pensei que sabia todos os operadores, até que eu vi um que está presente no Javascript desde 1996. Ele é suportado por todos os navegadores e é bem fácil de entender. Veja um trecho retirado do MDN:
O operador void avalia a expressão e depois retorna undefined.
Isso nos permite escrever um IIFE alternativo como esse:
void function iife() {
console.log('hello');
}();
// é o mesmo que ...
(function iife() {
console.log('hello');
})();
Uma coisa ruim com void é o fato de o retorno da função ser undefined.
const word = void function iife() {
return 'hello';
}();
// word é "undefined"
const word = (function iife() {
return 'hello';
})();
// word é "hello"
Você também pode usar void com async, utilizando como um ponto de entrada assíncrono para o seu código:
void async function() {
try {
const response = await fetch('air.ghost.io');
const text = await response.text();
console.log(text);
} catch(e) {
console.error(e);
}
}();
// ou faça apenas assim :)
(async () => {
try {
const response = await fetch('air.ghost.io');
const text = await response.text();
console.log(text);
} catch(e) {
console.error(e);
}
})();
Operador de vírgula
Depois de ler sobre o operador de vírgula, eu percebi que eu não estava totalmente ciente de como o mesmo funcionava. Veja um ótimo trecho retirado do MDN:
O operador de vírgula avalia cada um de seus operandos(da esqueda para a direita) e retorna o valor de seu último operando.
function myFunc() {
let x = 0;
return (x += 1, x); // mesmo que return ++x;
}
y = false, true; // retorna true no console
console.log(y); // false (mais à esquerda)
z = (false, true); // retorna true no console
console.log(z); // true (mais à direita)
Usando operador condicional
O último valor no operador de vírgula será o valor retornado para a condicional. Então você pode colocar qualquer número de expressões antes. No exemplo abaixo eu coloco um console log antes de retornar um booleano.
const type = 'man';
const isMale = type === 'man' ? (
console.log('Hi Man!'),
true
) : (
console.log('Hi Lady!'),
false
);
console.log(`isMale is "${isMale}"`);
API de Internacionalização
A Internacionalização era uma coisa difícil de se trabalhar há pouco tempo atrás, felizmente existe uma API com bom suporte atualmente na maioria dos navegadores. Uma das minhas features favoritas é o formatador de datas. Veja o exemplo abaixo.
const date = new Date();
const options = {
year: 'numeric',
month: 'long',
day: 'numeric'
};
const formatter1 = new Intl.DateTimeFormat('es-es', options);
console.log(formatter1.format(date)); // 22 de diciembre de 2017
const formatter2 = new Intl.DateTimeFormat('en-us', options);
console.log(formatter2.format(date)); // December 22, 2017
Pipeline operator
No momento em que eu estava escrevendo este artigo, o operador pipeline só tinha suporte no Firefox 58+ com uma flag, entretanto, o Babel tem um plugin para lidar com essa situação. Eu gosto bastante desse.
const square = (n) => n * n;
const increment = (n) => n + 1;
// sem pipeline operator
square(increment(square(2))); // 25
// com pipeline operator
2 |> square |> increment |> square; // 25
Menções importantes
Atômicos
Operações atômicas nos permite leitura e escrita previsíveis de valores quando os dados são compartilhados entre múltiplas threads, esperando que outras operações encerrem antes que a próxima seja executada. Operações atômicas são bastante úteis para manter dados síncronos entre coisas como a thread principal e outro WebWorker. Eu gosto bastante disso em outras linguagens, como Java. Eu sinto que elas serão mais usadas em JS quando a maioria dos programadores começarem a usar WebWorkers para tirar operações da thread principal.
Array.prototype.reduceRight
Ok, eu nunca tinha usado este porque é basicamente Array.prototype.reduce() + Array.prototype.reverse() e é bem difícil que você precise dessa combinação. Mas, se você precisar, ReduceRight é perfeito para você!
const achatado = [[0, 1], [2, 3], [4, 5]].reduceRight(function(a, b) {
return a.concat(b);
}, []);
// o array achatado é [4, 5, 2, 3, 0, 1]
Parâmetros do setTimeOut()
Eu provavelmente teria me poupado de um .bind(…) ou dois por saber disso - agora tem sido assim.
setTimeout(alert, 1000, 'Hello world!');
/*
* # Output (alert)
* Hello World!
*/
function log(text, textTwo) {
console.log(text, textTwo);
}
setTimeout(log, 1000, 'Hello World!', 'And Mars!');
/*
* # Output
* Hello World! And Mars!
*/
HTMLElement.dataset
Eu sempre usei data attributes personalizados (data -**) nos elementos HTML, mas, infelizmente, eu não estava ciente que havia uma API para consultá-los facilmente, até agora. Além de algumas restrições de nomenclarura (ver este link) a api é basicamente *dash-case para atributos e camelCase quando forem consultados no JS. Então o atributo data-birth-planet seria birthPlanet em JavaScript.
<div id='person' data-name='john' data-birth-planet='earth'></div>
Query:
let personEl = document.querySelector('#person');
console.log(personEl.dataset) // DOMStringMap {name: "john", birthPlanet: "earth"}
console.log(personEl.dataset.name) // john
console.log(personEl.dataset.birthPlanet) // earth
// Você pode adicionar mais se quiser
personEl.dataset.foo = 'bar';
console.log(personEl.dataset.foo); // bar
Fim
Espero que você tenha descoberto algo novo de JavaScript assim como eu. Parabéns ao Mozilla pelo novo site do MDN, está muito melhor, na minha opinião – Eu passei muito mais tempo lendo nele do que eu pensava que iria. Feliz 2018!