Voltar para o Blog

ECMAScript 2025: O Guia Completo das Novas Features do JavaScript

Ola HaWkers, em junho de 2025, a 129a Assembleia Geral aprovou oficialmente a especificacao ECMAScript 2025, trazendo algumas das features mais aguardadas pela comunidade JavaScript.

Voce ja esta usando essas novidades? Vamos explorar cada uma em detalhes, com exemplos praticos que voce pode aplicar hoje.

Iterator Helpers: A Feature Principal

A adicao mais significativa do ES2025 sao os Iterator Helpers - um novo objeto built-in Iterator com operadores funcionais que transformam como trabalhamos com colecoes.

Por Que Isso Importa

Diferente de Arrays que avaliam imediatamente e produzem arrays intermediarios em cada etapa, Iterator trabalha como outras APIs de estilo funcional onde cada operador e processado elemento por elemento.

// Antes (Arrays): Cria arrays intermediarios
const result = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
  .filter(n => n % 2 === 0)  // Cria array [2, 4, 6, 8, 10]
  .map(n => n * 2)            // Cria array [4, 8, 12, 16, 20]
  .slice(0, 3);               // Cria array [4, 8, 12]

// Agora (Iterator): Processa sob demanda
const iterator = Iterator.from([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
  .filter(n => n % 2 === 0)
  .map(n => n * 2)
  .take(3);

// So processa quando consumido
const result = [...iterator]; // [4, 8, 12]

Metodos Disponiveis

// Iterator.from() - Converte iteraveis em Iterator
const iter = Iterator.from([1, 2, 3]);
const mapIter = Iterator.from(new Map([['a', 1], ['b', 2]]));

// .map() - Transforma cada elemento
const doubled = Iterator.from([1, 2, 3])
  .map(x => x * 2)
  .toArray(); // [2, 4, 6]

// .filter() - Filtra elementos
const evens = Iterator.from([1, 2, 3, 4, 5])
  .filter(x => x % 2 === 0)
  .toArray(); // [2, 4]

// .take() - Pega os primeiros N elementos
const first3 = Iterator.from([1, 2, 3, 4, 5])
  .take(3)
  .toArray(); // [1, 2, 3]

// .drop() - Ignora os primeiros N elementos
const after2 = Iterator.from([1, 2, 3, 4, 5])
  .drop(2)
  .toArray(); // [3, 4, 5]

// .flatMap() - Map + flatten
const flattened = Iterator.from([[1, 2], [3, 4]])
  .flatMap(arr => arr)
  .toArray(); // [1, 2, 3, 4]

Exemplo Pratico: Processamento de Dados

// Processando um arquivo CSV grande linha por linha
async function* readCSVLines(filePath) {
  const file = await Deno.open(filePath);
  const decoder = new TextDecoder();

  for await (const chunk of file.readable) {
    const lines = decoder.decode(chunk).split('\n');
    for (const line of lines) {
      yield line;
    }
  }
}

// Usando Iterator Helpers para processar
const processedData = Iterator.from(readCSVLines('dados.csv'))
  .filter(line => line.trim().length > 0)     // Remove linhas vazias
  .drop(1)                                      // Ignora cabecalho
  .map(line => line.split(','))                 // Parse CSV
  .filter(([id, name]) => name.startsWith('A')) // Filtra por nome
  .take(100)                                    // Apenas 100 primeiros
  .map(([id, name, value]) => ({               // Transforma em objeto
    id: parseInt(id),
    name,
    value: parseFloat(value)
  }));

// Consome apenas o necessario
for (const record of processedData) {
  console.log(record);
}

Novos Metodos de Set

O ES2025 adiciona metodos matematicos ao Set, tornando-o muito mais versatil.

Operacoes de Conjunto

const setA = new Set([1, 2, 3, 4, 5]);
const setB = new Set([4, 5, 6, 7, 8]);

// .union() - Todos os elementos de ambos
const union = setA.union(setB);
// Set {1, 2, 3, 4, 5, 6, 7, 8}

// .intersection() - Elementos em comum
const intersection = setA.intersection(setB);
// Set {4, 5}

// .difference() - Elementos em A que nao estao em B
const difference = setA.difference(setB);
// Set {1, 2, 3}

// .symmetricDifference() - Elementos que estao em A ou B, mas nao ambos
const symDiff = setA.symmetricDifference(setB);
// Set {1, 2, 3, 6, 7, 8}

// .isSubsetOf() - A esta contido em B?
const isSubset = new Set([1, 2]).isSubsetOf(setA);
// true

// .isSupersetOf() - A contem B?
const isSuperset = setA.isSupersetOf(new Set([1, 2]));
// true

// .isDisjointFrom() - A e B nao tem elementos em comum?
const isDisjoint = setA.isDisjointFrom(new Set([10, 11]));
// true

Caso de Uso: Sistema de Permissoes

class PermissionManager {
  constructor() {
    this.rolePermissions = new Map();
  }

  defineRole(role, permissions) {
    this.rolePermissions.set(role, new Set(permissions));
  }

  getUserPermissions(roles) {
    // Une todas as permissoes de todos os roles
    return roles.reduce(
      (allPerms, role) => allPerms.union(
        this.rolePermissions.get(role) ?? new Set()
      ),
      new Set()
    );
  }

  hasAccess(userRoles, requiredPermissions) {
    const userPerms = this.getUserPermissions(userRoles);
    const required = new Set(requiredPermissions);

    // Verifica se usuario tem todas as permissoes necessarias
    return required.isSubsetOf(userPerms);
  }

  getMissingPermissions(userRoles, requiredPermissions) {
    const userPerms = this.getUserPermissions(userRoles);
    const required = new Set(requiredPermissions);

    // Retorna permissoes que faltam
    return required.difference(userPerms);
  }
}

// Uso
const pm = new PermissionManager();

pm.defineRole('admin', ['read', 'write', 'delete', 'manage']);
pm.defineRole('editor', ['read', 'write']);
pm.defineRole('viewer', ['read']);

const userRoles = ['editor', 'viewer'];
const required = ['read', 'write', 'delete'];

console.log(pm.hasAccess(userRoles, required)); // false
console.log([...pm.getMissingPermissions(userRoles, required)]); // ['delete']

Promise.try()

A nova Promise.try() espelha como uma funcao async se comporta, permitindo executar funcoes sincronamente quando possivel, enquanto ainda captura erros com seguranca.

// Problema: Tratamento inconsistente de erros
function processSyncOrAsync(data) {
  if (typeof data === 'string') {
    // Sincrono - erro nao capturado por .catch()
    return JSON.parse(data);
  } else {
    // Assincrono
    return fetch(data.url).then(r => r.json());
  }
}

// Solucao antiga (verbose)
function processSafe(data) {
  return new Promise(resolve => {
    resolve(processSyncOrAsync(data));
  });
}

// Solucao ES2025 (elegante)
function processModern(data) {
  return Promise.try(() => {
    if (typeof data === 'string') {
      return JSON.parse(data);
    } else {
      return fetch(data.url).then(r => r.json());
    }
  });
}

// Uso uniforme
processModern('{"name": "test"}')
  .then(data => console.log(data))
  .catch(err => console.error('Erro capturado:', err));

RegExp.escape()

O novo metodo estatico RegExp.escape() previne ataques de injecao em strings de expressao regular.

// Problema: Input do usuario pode quebrar regex
const userInput = "preço: $100.00 (desconto)";

// Perigoso - caracteres especiais quebram a regex
// const unsafeRegex = new RegExp(userInput); // Erro!

// Solucao ES2025
const safePattern = RegExp.escape(userInput);
// "preço: \\$100\\.00 \\(desconto\\)"

const safeRegex = new RegExp(safePattern);
const text = "O preço: $100.00 (desconto) é ótimo!";

console.log(safeRegex.test(text)); // true

Uso em Busca de Texto

function highlightText(text, searchTerm) {
  // Escapa caracteres especiais do termo de busca
  const escapedTerm = RegExp.escape(searchTerm);
  const regex = new RegExp(`(${escapedTerm})`, 'gi');

  return text.replace(regex, '<mark>$1</mark>');
}

// Seguro mesmo com caracteres especiais
const result = highlightText(
  "O preço é $50.00 (ou R$250)",
  "$50.00 (ou"
);
// "O preço é <mark>$50.00 (ou</mark> R$250)"

Float16Array

O ES2025 adiciona Float16Array para trabalhar com numeros de ponto flutuante de meia precisao.

// Util para operacoes de GPU onde precisao total nao e necessaria
const float16Data = new Float16Array([1.5, 2.5, 3.5, 4.5]);

// DataView tambem ganha metodos
const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);

view.setFloat16(0, 3.14159, true);  // little-endian
const value = view.getFloat16(0, true);

console.log(value); // ~3.14 (precisao reduzida)

Por Que Float16 Importa

// Comparacao de uso de memoria
const count = 1000000;

const float64 = new Float64Array(count); // 8MB
const float32 = new Float32Array(count); // 4MB
const float16 = new Float16Array(count); // 2MB

// Para machine learning e graficos, Float16 oferece:
// - 75% menos memoria que Float64
// - 50% menos memoria que Float32
// - Processamento mais rapido em GPUs modernas

JSON Module Import

O ES2025 padroniza a importacao direta de JSON como modulo.

// Importa JSON diretamente (apenas arquivos locais)
import appConfig from './config.json' with { type: 'json' };

// Funciona com import dinamico tambem
const translations = await import('./i18n/pt-BR.json', {
  with: { type: 'json' }
});

// Uso
console.log(appConfig.apiUrl);
console.log(translations.default.welcome);

Duplicate Named Capture Groups

Agora voce pode usar o mesmo nome em duas partes de uma regex se apenas uma delas puder corresponder.

// Antes: Nomes precisavam ser unicos
const oldRegex = /(?<year>\d{4})-(?<month>\d{2})|(?<month2>\d{2})\/(?<year2>\d{4})/;

// ES2025: Mesmo nome em alternativas
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})|(?<month>\d{2})\/(?<year>\d{4})/;

const match1 = "2025-12".match(dateRegex);
console.log(match1.groups.year);  // "2025"
console.log(match1.groups.month); // "12"

const match2 = "12/2025".match(dateRegex);
console.log(match2.groups.year);  // "2025"
console.log(match2.groups.month); // "12"

RegExp v Flag (Unicode Sets)

O flag v e uma atualizacao do flag u, habilitando mais recursos relacionados a Unicode.

// Intersecao de classes de caracteres
const greekVowels = /[\p{Script=Greek}&&\p{Letter}&&[αεηιουω]]/v;

// Subtracao de classes
const nonDigitLetters = /[\p{Letter}--\p{Number}]/v;

// Uniao explicita
const alphanumericPlus = /[[\p{Letter}][\p{Number}][_-]]/v;

Compatibilidade e Adocao

Suporte de Navegadores (Dezembro 2025)

Feature Chrome Firefox Safari Node.js
Iterator Helpers 122+ 131+ 17.4+ 22+
Set Methods 122+ 127+ 17+ 22+
Promise.try 128+ 132+ 18+ 23+
RegExp.escape 136+ 134+ 18.2+ 23+
Float16Array 127+ 129+ 18+ 22+

Como Usar Hoje

// Verificacao de suporte
const supportsIteratorHelpers = typeof Iterator !== 'undefined';
const supportsSetMethods = typeof Set.prototype.union === 'function';
const supportsPromiseTry = typeof Promise.try === 'function';

// Polyfills disponiveis
// npm install core-js
import 'core-js/actual/iterator';
import 'core-js/actual/set';
import 'core-js/actual/promise';

Conclusao

O ECMAScript 2025 traz features que ja eram aguardadas ha anos pela comunidade JavaScript. Iterator Helpers e Set Methods em particular mudam fundamentalmente como trabalhamos com colecoes, oferecendo codigo mais limpo e performatico.

A melhor parte e que muitas dessas features ja estao disponiveis nos navegadores modernos. Comece a usa-las hoje e melhore a qualidade do seu codigo JavaScript.

Se voce quer aprofundar seus conhecimentos em JavaScript moderno, recomendo que de uma olhada em outro artigo: Passkeys e WebAuthn: O Guia Completo onde voce vai descobrir como implementar autenticacao moderna em suas aplicacoes.

Bora pra cima! 🦅

📚 Quer Aprofundar Seus Conhecimentos em JavaScript?

Este artigo cobriu as novas features do ES2025, mas ha muito mais para explorar no mundo do desenvolvimento moderno.

Desenvolvedores que investem em conhecimento solido e estruturado tendem a ter mais oportunidades 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

👉 Conhecer o Guia JavaScript

💡 Material atualizado com as melhores praticas do mercado

Comentários (0)

Esse artigo ainda não possui comentários 😢. Seja o primeiro! 🚀🦅

Adicionar comentário