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! đ