As novidades do JavaScript em 2022
Todos os meses temos diversas novidades nas nossas linguagens favoritas, o JavaScript não é diferente!
Nesse vídeo eu explico um pouco mais sobre o processo de lançamento de novas funcionalidades do JavaScript, se você ainda não assistiu, eu recomendo fortemente para poder entender melhor como tudo funciona!
Dito isso, a versão 2022 do ECMAScript, a especificação por trás do JS, está incrível e eu vou explorar com você todas as principais novidades!
Método .at() em todos os indexáveis#
Uma das novidades mais simples, mas ao mesmo tempo mais legais é a adição do método .at() em listas e qualquer outro indexável nativo, tipo strings.
O que ele faz é dar o item na posição pedida do array, por exemplo:
const carrinho = ['banana', 'maçã', 'pera']carrinho.at(0) // bananacarrinho.at(-1) // pera
// Fora do limitecarrinho.at(100) // undefinedE isso funciona para qualquer indexável, então se tivermos uma string:
const frase = 'O rato roeu a roupa do rei de Roma'
frase.at(0) // Ofrase.at(-1) // asyncÍndices de captura em RegExp#
Agora, além de trazer o match da sua Regex, o construtor das RegExp também trás uma lista de índices de onde aquele match começou e terminou, por exemplo:
const input = 'abcd'const match = /b(c)/.exec(input)const indices = match.indices
indices.length // 2matches.length // 2// O número de indices é igual ao numero de matches
indices[0] // [1,3] inicio/fim do primeiro match "b"input.slice(indices[0][0], indices[0][1]) // mesma coisa que match[0]Object.hasOwn#
Uma variação mais simples do Object.hasOwnProperty que retorna true para todas as propriedades que são diretamente pertencentes a um objeto (sem serem herdadas):
const livros = {}livros.paginas = 123
Object.hasOwn(livros, 'paginas') // trueObject.hasOwn(livros, 'toString') // false
// O 'in' verifica todas as propriedades'paginas' in livros // true'toString' in livros // trueCausas de erros com Error.cause#
Uma das principais mudanças e uma das que eu acho que vão ser mais úteis. Essa nova propriedade da classe erro mostra a causa do erro enviado.
const erro = new Error('Um erro', { cause: 'A causa desse erro' })
erro instanceof Error // trueerro.cause // 'A causa desse erro'O principal caso de uso é evitar que o objeto de erro seja passado diretamente:
try { naoFunciona();} catch (err) { throw new Error('naoFunciona failed!', { cause: err });}Top-level await#
Isso já está disponível no Node.js há um tempo, mas desde que temos os ESModules já é possível realizar o top-level await, ou seja, um await fora de uma async function:
// falha na implementação antigaawait Promise.resolve('🍎');// → SyntaxError: await is only valid in async function
// correção que a gente costuma fazer com IIFE(async function() { await Promise.resolve('🍎'); // → 🎉}());
// nova implementação de top-level awaitawait Promise.resolve('🍎') // '🍎'Class field declarations#
Nós FINALMENTE agora temos a declaração de propriedades de classe fora do construtor, ou seja, a gente pode declarar e atribuir um valor a uma propriedade de uma classe sem precisar de um construtor com this.prop = prop.
Isso já era bastante comum no TypeScript, mas agora está chegando nativamente ao JavaScript:
class Classe { /* ao invés de: constructor() { this.publicID = 42; } */ publicID = 42; // public field
/* ao invés de: static get staticPublicField() { return -1 } */ static campoEstatico = -1;
// propriedades privadas estáticas static #campoPrivadoEstatico = 'private';
//métodos privados #privateMethod() {}
// declarações estáticas com static declaration blocks static { // Executado quando a classe é criada }}Checagem de campos por reflexão de classe#
Esse é um caso de uso complicado, mas quando tentávamos checar uma propriedade de uma classe através de um bloco de inicialização estático, iríamos ter um erro dizendo que a classe não foi inicializada ou que a propriedade não existe, isso foi corrigido:
class C { #prop;
#metodo() {}
get #getter() {}
static isC(obj) { // usando 'in' return #prop in obj && #metodo in obj && #getter in obj; }}