ECMAScript 2025: Os Novos Recursos do JavaScript Que Voce Precisa Conhecer
Ola HaWkers, mais um ano e mais uma atualizacao do ECMAScript foi oficialmente aprovada pelo TC39. O ECMAScript 2025 traz recursos que podem parecer incrementais a primeira vista, mas que resolvem problemas reais que desenvolvedores enfrentam no dia a dia.
Voce ja teve dificuldades com regex complexas ou precisou otimizar memoria em aplicacoes graficas? As novidades deste ano abordam exatamente esses cenarios.
O Que Mudou no ECMAScript 2025
O processo de evolucao do JavaScript segue um ciclo anual bem definido. Propostas passam por estagios (Stage 0 a Stage 4) antes de serem incorporadas ao padrao oficial. Em 2025, temos algumas adicoes interessantes que ja estao disponiveis nos principais navegadores e runtimes.
Principais Adicoes
Recursos aprovados em ES2025:
- Float16Array - Novo TypedArray para precisao de 16 bits
- Duplicate Named Capture Groups - Regex mais flexiveis
- Set Methods - Operacoes de conjunto nativas
- Promise.try - Tratamento unificado de erros
- RegExp.escape - Escape seguro de strings para regex
- Import Attributes - Metadados em imports
Float16Array: Otimizacao de Memoria Para Graficos e IA
O Float16Array e uma das adicoes mais significativas para quem trabalha com WebGL, WebGPU ou machine learning no browser.
Por Que Float16 Importa
Ate agora, tinhamos apenas Float32Array e Float64Array. O problema? Muitas aplicacoes graficas e de IA nao precisam de tanta precisao, e usar 32 ou 64 bits desperdicava memoria.
// Comparacao de tamanho em bytes para 1000 elementos
const float64 = new Float64Array(1000); // 8000 bytes
const float32 = new Float32Array(1000); // 4000 bytes
const float16 = new Float16Array(1000); // 2000 bytes - NOVO!
console.log('Float64:', float64.byteLength, 'bytes');
console.log('Float32:', float32.byteLength, 'bytes');
console.log('Float16:', float16.byteLength, 'bytes');
// Float16 usa 50% menos memoria que Float32!Uso Pratico com WebGPU
// Criando buffer de vertices otimizado para WebGPU
const vertices = new Float16Array([
// x, y, z, u, v - coordenadas e texturas
-1.0, -1.0, 0.0, 0.0, 0.0,
1.0, -1.0, 0.0, 1.0, 0.0,
0.0, 1.0, 0.0, 0.5, 1.0,
]);
// Funcoes auxiliares para conversao
const value = 3.14159;
const f16Bits = Math.f16round(value); // Arredonda para Float16
// Verificar se o valor pode ser representado em Float16
function isFloat16Safe(num) {
const rounded = Math.f16round(num);
return Object.is(num, rounded) ||
(Number.isNaN(num) && Number.isNaN(rounded));
}
console.log(isFloat16Safe(0.1)); // true
console.log(isFloat16Safe(65536)); // false (overflow)DataView com Float16
const buffer = new ArrayBuffer(10);
const view = new DataView(buffer);
// Novos metodos do DataView
view.setFloat16(0, 3.14, true); // little-endian
view.setFloat16(2, 2.71, false); // big-endian
const pi = view.getFloat16(0, true);
const e = view.getFloat16(2, false);
console.log(pi); // ~3.140625 (precisao de 16 bits)
console.log(e); // ~2.710938
Duplicate Named Capture Groups
Este recurso resolve uma limitacao frustrante das regex em JavaScript: nao podiamos usar o mesmo nome em grupos de captura alternativos.
O Problema Anterior
// ANTES: Isso gerava erro de sintaxe!
// const dateRegex = /(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})\/(?<year>\d{4})/;
// SyntaxError: Duplicate capture group name
// Tinhamos que usar nomes diferentes
const dateRegexOld = /(?<year1>\d{4})-(?<month1>\d{2})|(?<month2>\d{2})\/(?<year2>\d{4})/;A Solucao em ES2025
// AGORA: Funciona perfeitamente!
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})\/(?<year>\d{4})/;
// Parsing de diferentes formatos de data
const dates = [
'2025-11-30', // formato ISO
'30/11/2025', // formato brasileiro
];
dates.forEach(date => {
const match = date.match(dateRegex);
if (match) {
console.log(`Ano: ${match.groups.year}, Mes: ${match.groups.month}`);
}
});
// Ano: 2025, Mes: 11
// Ano: 2025, Mes: 11Caso de Uso Real: Parser de Logs
// Parser flexivel para diferentes formatos de log
const logRegex = /
(?:\[(?<level>INFO|WARN|ERROR)\])|
(?:(?<level>info|warn|error):)
/xi;
const logs = [
'[ERROR] Database connection failed',
'warn: Memory usage high',
'[INFO] Server started',
];
logs.forEach(log => {
const match = log.match(logRegex);
if (match) {
const level = match.groups.level.toUpperCase();
console.log(`Nivel: ${level}`);
}
});
Set Methods: Operacoes de Conjunto Nativas
Finalmente temos metodos nativos para operacoes de conjunto que antes precisavamos implementar manualmente.
Novos Metodos Disponiveis
const setA = new Set([1, 2, 3, 4, 5]);
const setB = new Set([4, 5, 6, 7, 8]);
// Union - elementos em A ou B
const union = setA.union(setB);
console.log([...union]); // [1, 2, 3, 4, 5, 6, 7, 8]
// Intersection - elementos em A e B
const intersection = setA.intersection(setB);
console.log([...intersection]); // [4, 5]
// Difference - elementos em A mas nao em B
const difference = setA.difference(setB);
console.log([...difference]); // [1, 2, 3]
// Symmetric Difference - elementos em A ou B, mas nao em ambos
const symmetricDiff = setA.symmetricDifference(setB);
console.log([...symmetricDiff]); // [1, 2, 3, 6, 7, 8]Metodos de Verificacao
const admins = new Set(['alice', 'bob']);
const users = new Set(['alice', 'bob', 'charlie', 'diana']);
const guests = new Set(['eve', 'frank']);
// isSubsetOf - A esta contido em B?
console.log(admins.isSubsetOf(users)); // true
console.log(users.isSubsetOf(admins)); // false
// isSupersetOf - A contem B?
console.log(users.isSupersetOf(admins)); // true
// isDisjointFrom - A e B nao tem elementos em comum?
console.log(admins.isDisjointFrom(guests)); // true
console.log(admins.isDisjointFrom(users)); // falseAplicacao Pratica: Sistema de Permissoes
class PermissionManager {
constructor() {
this.roles = {
admin: new Set(['read', 'write', 'delete', 'manage_users']),
editor: new Set(['read', 'write']),
viewer: new Set(['read']),
};
}
hasAllPermissions(userPermissions, requiredPermissions) {
return requiredPermissions.isSubsetOf(userPermissions);
}
getMissingPermissions(userPermissions, requiredPermissions) {
return requiredPermissions.difference(userPermissions);
}
combineRoles(...roleNames) {
return roleNames.reduce((combined, role) => {
return combined.union(this.roles[role] || new Set());
}, new Set());
}
}
const pm = new PermissionManager();
const userPerms = pm.combineRoles('editor', 'viewer');
const required = new Set(['read', 'write', 'delete']);
console.log('Has all:', pm.hasAllPermissions(userPerms, required)); // false
console.log('Missing:', [...pm.getMissingPermissions(userPerms, required)]); // ['delete']
Promise.try: Tratamento Unificado de Erros
O Promise.try resolve um problema comum: quando voce tem uma funcao que pode ser sincrona ou assincrona e quer tratar erros de forma unificada.
O Problema
// ANTES: Codigo inconsistente
function processData(data) {
// Se isso lancar erro sincrono, o catch nao pega!
return validateSync(data)
.then(validated => transform(validated))
.catch(err => console.error(err));
}
// Solucao antiga (verbosa)
function processDataOld(data) {
return new Promise(resolve => resolve(validateSync(data)))
.then(validated => transform(validated))
.catch(err => console.error(err));
}A Solucao com Promise.try
// AGORA: Limpo e consistente
function processData(data) {
return Promise.try(() => validateSync(data))
.then(validated => transform(validated))
.catch(err => console.error(err));
}
// Funciona com funcoes sync e async
const result1 = Promise.try(() => {
return 42; // sincrono
});
const result2 = Promise.try(async () => {
const response = await fetch('/api/data');
return response.json(); // assincrono
});
// Erros sincronos sao capturados
const result3 = Promise.try(() => {
throw new Error('Sync error');
}).catch(err => {
console.log('Caught:', err.message); // Caught: Sync error
});RegExp.escape: Escape Seguro de Strings
Quando voce precisa usar input do usuario em uma regex, escapar caracteres especiais era manual e propenso a erros.
// ANTES: Funcao manual (comum em projetos)
function escapeRegExpOld(string) {
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
// AGORA: Metodo nativo
const userInput = 'Hello (World)? [Test]';
const escaped = RegExp.escape(userInput);
console.log(escaped); // Hello \(World\)\? \[Test\]
// Uso seguro em regex dinamica
function highlightText(text, searchTerm) {
const safePattern = RegExp.escape(searchTerm);
const regex = new RegExp(`(${safePattern})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
}
const result = highlightText(
'Price is $50 (special offer!)',
'$50 (special'
);
// Price is <mark>$50 (special</mark> offer!)
Import Attributes: Metadados em Imports
Import Attributes permitem passar informacoes adicionais ao importar modulos, especialmente util para JSON e outros tipos de arquivos.
// Importando JSON com type assertion
import config from './config.json' with { type: 'json' };
// Import dinamico com atributos
const data = await import('./data.json', {
with: { type: 'json' }
});
// Isso ajuda engines a otimizar e validar imports
// Tambem melhora a seguranca ao explicitar o tipo esperadoCompatibilidade e Adocao
Suporte nos Navegadores
| Recurso | Chrome | Firefox | Safari | Node.js |
|---|---|---|---|---|
| Float16Array | 127+ | 129+ | 18.2+ | 22+ |
| Duplicate Named Groups | 125+ | 128+ | 18+ | 22+ |
| Set Methods | 122+ | 127+ | 17+ | 22+ |
| Promise.try | 128+ | Em desenvolvimento | 18+ | 22+ |
| RegExp.escape | Em desenvolvimento | Em desenvolvimento | 18+ | 22+ |
Usando Hoje com Transpiladores
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
targets: { node: 'current' },
shippedProposals: true,
}],
],
};Conclusao
O ECMAScript 2025 pode nao ter o impacto visual de adicoes como async/await ou optional chaining, mas cada recurso resolve problemas praticos. Float16Array vai beneficiar aplicacoes graficas e de IA, os Set Methods simplificam codigo que antes era verboso, e Promise.try padroniza algo que desenvolvedores implementavam de formas diferentes.
A evolucao incremental do JavaScript mostra a maturidade da linguagem. Nao precisamos de revolucoes a cada ano; melhorias pontuais e bem pensadas mantem a linguagem moderna sem quebrar compatibilidade.
Se voce quer acompanhar mais novidades sobre JavaScript e desenvolvimento web, recomendo dar uma olhada no artigo sobre Svelte 5 e Runes onde exploramos outra inovacao que esta transformando como escrevemos codigo reativo.
Bora pra cima! 🦅
📚 Quer Aprofundar Seus Conhecimentos em JavaScript?
Este artigo cobriu as novidades do ECMAScript 2025, mas ha muito mais para explorar no ecossistema JavaScript.
Desenvolvedores que dominam os fundamentos e acompanham a evolucao da linguagem se destacam no mercado.
Material de Estudo Completo
Se voce quer dominar JavaScript do basico ao avancado, preparei um guia completo:
Opcoes de investimento:
- 1x de R$9,90 no cartao
- ou R$9,90 a vista
💡 Material atualizado com as melhores praticas do mercado

