ES08 - Novas features no JavaScript
Neste post vamos ficar por dentro das novidades do ES08 (ECMAScript 2017) no JavaScript.
Se quiser ver o que rolou no ES07 recomendo a leitura desse post.
Padding String
String ganhou dois métodos novos: padStart() e padEnd(). Padding significa preenchimento, portanto, vamos ver como preencher uma String no começo e no final.
Método padStart() recebe dois parâmetros: o primeiro é o tamanho final da string após a execução do padding; e o segundo parâmetro é o caractere que vai preencher até alcançar o tamanho da String. O preenchimento é feito da esquerda para direita, isso é, do inÃcio da String até o final.
Veja abaixo alguns exemplos:
// Preenchendo dois zeros no começo da string
const filme = '7';
console.log(`${filme.padStart(3, '00')} - Sem Tempo Para Morrer`)
// 007 - Sem Tempo Para Morrer
// Adivinhando o nome
const nome = "Thiago" // Nome para adivinhar.
const ultimaLetraDoNome = nome.slice(nome.length - 1)
console.log(`Uma dica: Termina com '${ultimaLetraDoNome}', e tem ${nome.length} letras`,)
// "Uma dica: Termina com 'o', e tem 6 letras"
let adivinheMeuNome = ultimaLetraDoNome.padStart(nome.length, '*');
console.log(adivinheMeuNome) // Resultado: "*****o"
console.log(`Resposta correta: ${nome}`) // Resposta correta: Thiago
// Escondendo alguns dÃgitos do cartão de crédito
const cartaoDeCredito = '2034399002125581';
const ultimosQuatroDigitos = cartaoDeCredito.slice(-4);
const cartaoDeCreditoMask = ultimosQuatroDigitos.padStart(cartaoDeCredito.length, '*');
// Resultado: "************5581"
- padEnd()
Mesma funcionalidade do padStart(), porém o preenchimento começa do fim (direita) da String. Se receber apenas um parâmetro, será adicionando um espaço vazio, ao invés de um caractere, caso receba apenas um parâmetro. Demonstramos no primeiro exemplo abaixo:
// Adicionando dois espaços em branco após: '200'
const string = '200';
console.log(string.padEnd(5)); // Resultado: "200 "
// Observe que o tamanho da string é cinco passou a ser cinco.
// Array de números
const numbers = [1, 2, 3, 4, 5]
// Crio um novo array de Strings Adicionando ". " em cada número e converto para String.
const ordenedList = numbers.map(number => String(number).padEnd(3, '. '))
console.log(ordenedList)
// Resultado: ["1. ", "2. ", "3. ", "4. ", "5. "]
// Adicionando reticências.
const txtLoading = 'Loading';
console.log(txtLoading.padEnd(10, '.')); // "Loading..."
Trailing commas
VÃrgulas no final. Para ser sincero não é muito útil. DifÃcil achar algum caso de uso para essa funcionalidade. Ela basicamente permite você colocar uma ,
após o último elemento de um array ou objeto, e não dará um erro de sintaxe.
// Exemplo com Array
const numbers = [1,2,3,]
console.log(numbers) // 1, 2, 3
// Exemplo com Objeto
const tech = {
name: 'JavaScript',
sigla: 'JS',
age: 24,
}
Em funções também é possÃvel colocar vÃrgulas no final:
function sum(n1, n2,) { return n1 + n2 }
sum(1,2) // 3 válido
sum(1,3,) // 4 válido
Mas claro que alguns erros de sintaxe podem ocorrer:
function sum(, ) { }
// Uncaught SyntaxError: Unexpected token ','
Vale a pena saber que existe, mas não é algo que é aplicado no dia a dia. Com uma regra no ESLint essas vÃrgulas no final são removidas automaticamente, caso prefira.
Objects: entries() e values()
- Object.entries()
Retorna um array com chave e valor de cada atributo do objeto em um array: [ [name: 'Thiago'], [email: 'oi@email.com'] ]
. O que torna possÃvel fazer iteração entre cada propriedade utilizando o for ... of
 como no exemplo abaixo:
const rocketseat = {
backend: 'Node.js',
frontend: 'React',
mobile: 'React Native',
}
for (const [prop, value] of Object.entries(rocketseat)) {
console.log(`${prop}: ${value}`);
}
// SaÃda:
/**
backend: Node.js
frontend: React
mobile: React Native
*/
- Object.values()
Retorna um array com os valores de cada atributo do objeto.
const rocketseat = {
backend: 'Node.js',
frontend: 'React',
mobile: 'React Native',
}
// Antes
for (const key in rocketseat) {
if (rocketseat.hasOwnProperty(key)) {
const value = rocketseat[key];
console.log(value); // "Node.js", "React", "React Native"
}
}
// Abordagem Funcional - ES6
console.log(Object.keys(rocketseat).map((k) => rocketseat[k]));
// ["Node.js", "React", "React Native"]
// Hoje - ES8
console.log(Object.values(rocketseat));
// ["Node.js", "React", "React Native"]
// Outros exemplos com String:
console.log(Object.values('Rocksetseat'))
// ["R", "o", "c", "k", "s", "e", "t", "s", "e", "a", "t"]
console.log(Object.entries('Rocksetseat'))
// [["0", "R"], ["1","o"] .... ["10", "t"]]
Object.getOwnPropertyDescriptors()
Retorna uma descrição do objeto que foi informado no parâmetro.
const rocketseat = {
backend: 'Node.js',
frontend: 'React',
mobile: 'React Native',
}
console.log(Object.getOwnPropertyDescriptors(rocketseat))
// Resultado
/**
{
backend: {
value: 'Node.js',
writable: true,
enumerable: true,
configurable: true
},
frontend: {
value: 'React',
writable: true,
enumerable: true,
configurable: true
},
mobile: {
value: 'React Native',
writable: true,
enumerable: true,
configurable: true
}
}
*/
const arrayFunc = () => {}
console.log(Object.getOwnPropertyDescriptors(arrayFunc))
// Saida
/**
{
length: { value: 0, writable: false, enumerable: false, configurable: true },
name: {
value: 'arrayFunc',
writable: false,
enumerable: false,
configurable: true
}
}
*/
Esse método ajuda a criar uma cópia profunda do objeto, de maneira que o clone do mesmo se torne fiel à sua matriz.
const rocketseat = {
backend: "Node.js",
frontend: "React",
mobile: "React Native",
};
console.log(rocketseat);
// Clonando
const UICloneRocketseat = Object.defineProperties(
{},
Object.getOwnPropertyDescriptors(rocketseat)
);
// Resultado
console.log(UICloneRocketseat);
console.log(Object.getOwnPropertyDescriptors(UICloneRocketseat));
Funções AssÃncronas
Melhoram a experiência da programação assÃncrona. Async/Await são palavras reservadas que usamos em funções assÃncronas. Com essa nova sintaxe podemos escrevê-las de maneira mais coesa. A quantidade de código não reduz muito, mas dá para perceber a sua clareza, veja os exemplos abaixo:
// Async Function
async function getUserUsingAsyncAwait(username) {
try {
const response = await fetch(`https://api.github.com/users/${username}`);
return response.json()
} catch (err) {
console.log("Ops! Ocorreu um erro...", err);
}
}
// Função com Promises
function getUserUsingPromises(username) {
return fetch(`https://api.github.com/users/${username}`)
.then(response => response.json())
.then(json => {
return json
}).catch(err => {
console.error('Ops! Ocorreu um erro...', err);
});
}
// https://developer.mozilla.org/pt-BR/docs/Glossario/IIFE
// IIFE (Immediately Invoked Function Expression)
// é uma função em JavaScript que é executada assim que definida.
(async function(){
console.log(await getUserUsingAsyncAwait('vinifraga'))
console.log(await getUserUsingPromises('jpedroschmitz'))
})()
Veja o código funcionando no Codepen.
function resolveDepoisDeDoisSegundos(x) {
return new Promise((resolve) => {
setTimeout(() => {
resolve(x);
}, 2000);
});
}
(async function (x) {
// async function expression usada como uma IIFE
const a = resolveDepoisDeDoisSegundos(20);
const b = resolveDepoisDeDoisSegundos(30);
return x + (await a) + (await b);
})(10).then((valor) => {
console.log(valor); // imprime 60 após 2 segundo.
});
const soma = async function (valor) {
// async function expression atribuÃda a uma constante
const a = await resolveDepoisDeDoisSegundos(20);
const b = await resolveDepoisDeDoisSegundos(30);
return valor + a + b;
};
soma(10).then((valor) => {
console.log(valor); // imprime 60 após 4 segundos.
});
Conclusão
Sem dúvida nenhuma que Funções AssÃncronas é a feature mais utilizada e útil desse lançamento. Você precisa aprender para alcançar o próximo nÃvel e deixar o código mais legÃvel, Async/Await é um syntactic sugar que deixa o código mais agradável, se quiser saber quando usar Async/Await ou sobre Promises no Frontend com React dá uma lida aqui.
Object.values() e Object.entries() são bastantes utilizadas também no dia a dia.
O método Object.getOwnPropertyDescriptors() creio que é o menos utilizado até porque para fazer cópias de objetos podemos utilizar o Object.assign() ou o famoso e apreciado Spread Operador.
Links
- https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Statements/funcoes_assincronas
- https://developers.google.com/web/fundamentals/primers/async-functions
- https://www.digitalocean.com/community/tutorials/js-getownpropertydescriptors
- https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction
- https://blog.rocketseat.com.br/es07-novas-features-no-javascript/
E aÃ, o que achou do post?
Espero que tenha curtido! 💜
O aprendizado é contÃnuo e sempre haverá um próximo nÃvel! 🚀