<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('https://api.exemplo.com/dados').then(r => 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: 'Ana', role: 'admin' },
{ nome: 'Bruno', role: 'user' },
{ nome: 'Carlos', role: 'admin' },
{ nome: 'Diana', role: 'user' }
];
const porRole = Object.groupBy(usuarios, u => u.role);
// Resultado:
// {
// admin: [{ nome: 'Ana', role: 'admin' }, { nome: 'Carlos', role: 'admin' }],
// user: [{ nome: 'Bruno', role: 'user' }, { nome: 'Diana', role: 'user' }]
// }
const porRoleMap = Map.groupBy(usuarios, u => u.role);
console.log(porRoleMap.get('admin')); // 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 => n > 10); // 44
const indice = numeros.findLastIndex(n => n > 10); // 4
const ordenado = numeros.toSorted((a, b) => 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) => {
resolve = res;
reject = rej;
});
return { promise, resolve, reject };
}
// Depois: ES2024
const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(() => resolve('sucesso!'), 1000);
promise.then(resultado => 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 = "gato gato gato";
console.log(texto.replaceAll('gato', 'cachorro'));
// "cachorro cachorro cachorro"
// ??= (nullish coalescing assignment)
let config = null;
config ??= { tema: 'escuro', idioma: 'pt-BR' };
console.log(config); // { tema: 'escuro', idioma: 'pt-BR' }
let config2 = { tema: 'claro' };
config2 ??= { tema: 'escuro' };
console.log(config2); // { tema: 'claro' } - 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: 'OK' },
{ timestamp: Date.now() - 1000, status: 500, mensagem: 'Erro' },
{ timestamp: Date.now() - 2000, status: 200, mensagem: 'OK' },
{ timestamp: Date.now() - 3000, status: 404, mensagem: 'Não encontrado' },
{ timestamp: Date.now() - 4000, status: 200, mensagem: 'OK' }
];
// Agrupar por status e pegar últimos 3 de cada grupo
const agrupado = Object.groupBy(logs, l => l.status);
const resumo = Object.entries(agrupado).map(([status, items]) => ({
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>