JavaScript

Como Usar Novidades do ECMAScript: ES2022, ES2023 e ES2024 na Prática em Produção

7 min de leitura

Como Usar Novidades do ECMAScript: ES2022, ES2023 e ES2024 na Prática em Produção

ES2022: Top-Level Await e Class Fields O ES2022 trouxe melhorias significativas para módulos e orientação a objetos. O top-level await permite usar diretamente no corpo de um módulo, sem envolvê-lo em uma função . Isso simplifica a inicialização de dados antes da execução do código principal. Os campos de classe privada ( ) e o operador para verificação trazem encapsulamento real. Diferente de convenções anteriores, campos privados são verdadeiramente inacessíveis fora da classe. O método em arrays permite acesso negativo elegante, retorna o último elemento sem contar o tamanho. ES2023: Array Grouping e Métodos de String Melhorados O e revolucionaram agregação de dados, substituindo lógicas complexas por uma única função. Este método agrupa elementos conforme um critério definido, retornando um objeto ou mapa com as categorias como chaves. Os métodos e implementam a busca em ordem reversa de forma nativa. , e criam cópias ordenadas/modificadas sem alterar o array original—crucial para programação imutável. ES2024: Promise.withResolvers e Array Methods Finais O

<h2>ES2022: Top-Level Await e Class Fields</h2>

<p>O ES2022 trouxe melhorias significativas para módulos e orientação a objetos. O <strong>top-level await</strong> permite usar <code>await</code> diretamente no corpo de um módulo, sem envolvê-lo em uma função <code>async</code>. Isso simplifica a inicialização de dados antes da execução do código principal.</p>

<pre><code class="language-javascript">// Antes: precisava de uma IIFE ou função async

// Depois: ES2022

const dados = await fetch(&#039;https://api.exemplo.com/dados&#039;).then(r =&gt; r.json());

console.log(dados);</code></pre>

<p>Os <strong>campos de classe privada</strong> (<code>#</code>) e o operador <code>in</code> para verificação trazem encapsulamento real. Diferente de convenções anteriores, campos privados são verdadeiramente inacessíveis fora da classe. O método <code>.at()</code> em arrays permite acesso negativo elegante, <code>array.at(-1)</code> retorna o último elemento sem contar o tamanho.</p>

<pre><code class="language-javascript">class Usuario {

#senha; // campo privado verdadeiro

constructor(nome, senha) {

this.nome = nome;

this.#senha = senha;

}

verificarSenha(teste) {

return teste === this.#senha;

}

static criar(dados) { // static inicializer blocks

return new Usuario(dados.nome, dados.senha);

}

}

const arr = [10, 20, 30];

console.log(arr.at(-1)); // 30

console.log(arr.at(-2)); // 20</code></pre>

<h2>ES2023: Array Grouping e Métodos de String Melhorados</h2>

<p>O <strong><code>Object.groupBy()</code></strong> e <strong><code>Map.groupBy()</code></strong> revolucionaram agregação de dados, substituindo lógicas complexas por uma única função. Este método agrupa elementos conforme um critério definido, retornando um objeto ou mapa com as categorias como chaves.</p>

<pre><code class="language-javascript">const usuarios = [

{ nome: &#039;Ana&#039;, role: &#039;admin&#039; },

{ nome: &#039;Bruno&#039;, role: &#039;user&#039; },

{ nome: &#039;Carlos&#039;, role: &#039;admin&#039; },

{ nome: &#039;Diana&#039;, role: &#039;user&#039; }

];

const porRole = Object.groupBy(usuarios, u =&gt; u.role);

// Resultado:

// {

// admin: [{ nome: &#039;Ana&#039;, role: &#039;admin&#039; }, { nome: &#039;Carlos&#039;, role: &#039;admin&#039; }],

// user: [{ nome: &#039;Bruno&#039;, role: &#039;user&#039; }, { nome: &#039;Diana&#039;, role: &#039;user&#039; }]

// }

const porRoleMap = Map.groupBy(usuarios, u =&gt; u.role);

console.log(porRoleMap.get(&#039;admin&#039;)); // array de admins</code></pre>

<p>Os métodos <code>.findLast()</code> e <code>.findLastIndex()</code> implementam a busca em ordem reversa de forma nativa. <code>.toSorted()</code>, <code>.toReversed()</code> e <code>.toSpliced()</code> criam cópias ordenadas/modificadas sem alterar o array original—crucial para programação imutável.</p>

<pre><code class="language-javascript">const numeros = [5, 12, 8, 130, 44];

const ultimo = numeros.findLast(n =&gt; n &gt; 10); // 44

const indice = numeros.findLastIndex(n =&gt; n &gt; 10); // 4

const ordenado = numeros.toSorted((a, b) =&gt; a - b); // cópia ordenada

const invertido = numeros.toReversed(); // cópia invertida

console.log(numeros); // original intacto: [5, 12, 8, 130, 44]</code></pre>

<h2>ES2024: Promise.withResolvers e Array Methods Finais</h2>

<p>O <strong><code>Promise.withResolvers()</code></strong> extrai <code>resolve</code> e <code>reject</code> do construtor da Promise, tornando padrões como executores repetidos mais limpos. Em vez de envolver código em <code>new Promise()</code>, você obtém a promise e os controladores separadamente.</p>

<pre><code class="language-javascript">// Antes:

function criarPromise() {

let resolve, reject;

const promise = new Promise((res, rej) =&gt; {

resolve = res;

reject = rej;

});

return { promise, resolve, reject };

}

// Depois: ES2024

const { promise, resolve, reject } = Promise.withResolvers();

setTimeout(() =&gt; resolve(&#039;sucesso!&#039;), 1000);

promise.then(resultado =&gt; console.log(resultado)); // sucesso!</code></pre>

<p>Os métodos <code>.findLast()</code> e <code>.findLastIndex()</code> que começaram em ES2023 agora têm suporte universal. O <strong><code>String.prototype.replaceAll()</code></strong> (já em ES2021, mas consolidado) é essencial para substituir todas as ocorrências sem regex global. O <strong>novo operador <code>??=</code></strong> (nullish coalescing assignment) atualiza variáveis apenas se forem <code>null</code> ou <code>undefined</code>.</p>

<pre><code class="language-javascript">// replaceAll

const texto = &quot;gato gato gato&quot;;

console.log(texto.replaceAll(&#039;gato&#039;, &#039;cachorro&#039;));

// &quot;cachorro cachorro cachorro&quot;

// ??= (nullish coalescing assignment)

let config = null;

config ??= { tema: &#039;escuro&#039;, idioma: &#039;pt-BR&#039; };

console.log(config); // { tema: &#039;escuro&#039;, idioma: &#039;pt-BR&#039; }

let config2 = { tema: &#039;claro&#039; };

config2 ??= { tema: &#039;escuro&#039; };

console.log(config2); // { tema: &#039;claro&#039; } - não foi alterado</code></pre>

<h2>Padrões Práticos: Integrando as Novidades</h2>

<p>Na prática profissional, essas features se combinam para código mais expressivo. Um exemplo real: processar logs de API, agrupar por status, e retornar as últimas 3 respostas por grupo usando ES2023+2024.</p>

<pre><code class="language-javascript">const logs = [

{ timestamp: Date.now(), status: 200, mensagem: &#039;OK&#039; },

{ timestamp: Date.now() - 1000, status: 500, mensagem: &#039;Erro&#039; },

{ timestamp: Date.now() - 2000, status: 200, mensagem: &#039;OK&#039; },

{ timestamp: Date.now() - 3000, status: 404, mensagem: &#039;Não encontrado&#039; },

{ timestamp: Date.now() - 4000, status: 200, mensagem: &#039;OK&#039; }

];

// Agrupar por status e pegar últimos 3 de cada grupo

const agrupado = Object.groupBy(logs, l =&gt; l.status);

const resumo = Object.entries(agrupado).map(([status, items]) =&gt; ({

status,

ultimos: items.toReversed().slice(0, 3)

}));

console.log(resumo);

// Mostra os 3 últimos logs de cada código de status</code></pre>

<h2>Conclusão</h2>

<p>As novidades ES2022-2024 não são apenas açúcar sintático—elas resolvem problemas reais de forma elegante. <strong>Top-level await</strong> e <strong>campos privados</strong> melhoram a estrutura do código; <strong>Object.groupBy()</strong> e métodos de array imutáveis eliminam boilerplate; <strong>Promise.withResolvers()</strong> simplifica padrões async comuns. Dominar essas features torna você um desenvolvedor moderno e produtivo. Comece aplicando-as em seus projetos e note a redução de complexidade.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers" target="_blank" rel="noopener noreferrer">MDN Web Docs - ES2022 Features</a></li>

<li><a href="https://tc39.es/ecma262/" target="_blank" rel="noopener noreferrer">ECMAScript 2024 Proposal Specifications</a></li>

<li><a href="https://javascript.info/" target="_blank" rel="noopener noreferrer">JavaScript.info - Modern JavaScript Features</a></li>

<li><a href="https://eloquentjavascript.net/" target="_blank" rel="noopener noreferrer">Eloquent JavaScript - 3rd Edition</a></li>

<li><a href="https://nodejs.org/en/docs/guides/ecmascript-2015-features/" target="_blank" rel="noopener noreferrer">Node.js Documentation - ES Modules</a></li>

</ul>

Comentários

Mais em JavaScript

Como Usar Optional Chaining, Nullish Coalescing e Logical Assignment em JS em Produção
Como Usar Optional Chaining, Nullish Coalescing e Logical Assignment em JS em Produção

Optional Chaining (?.) O Optional Chaining é um operador que permite acessar...

Boas Práticas de Promises em JavaScript: then, catch, finally e Encadeamento para Times Ágeis
Boas Práticas de Promises em JavaScript: then, catch, finally e Encadeamento para Times Ágeis

O que é uma Promise? Uma Promise é um objeto JavaScript que representa o resu...

Boas Práticas de Tratamento de Erros Assíncronos em JavaScript na Prática para Times Ágeis
Boas Práticas de Tratamento de Erros Assíncronos em JavaScript na Prática para Times Ágeis

Entendendo Promises e seu Tratamento de Erros Uma Promise é a base do tratame...