desenvolvimento

JavaScript ES2024: Novidades que vão mudar sua forma de programar

Ricardo Laurito

Ricardo Laurito

UI/UX Designer e Desenvolvedor Web especializado em React e Next

12 ene 2025 6 min de leitura
HomeBlogdesenvolvimento

JavaScript ES2024: Novidades que vão mudar sua forma de programar

O JavaScript continua evoluindo rapidamente. O ES2024 trouxe funcionalidades incríveis que vão transformar a forma como escrevemos código. Vamos explorar as principais novidades.

1. Array grouping

Agrupe elementos de array de forma nativa:

const products = [
  { name: 'iPhone', category: 'electronics', price: 999 },
  { name: 'Shirt', category: 'clothing', price: 29 },
  { name: 'Laptop', category: 'electronics', price: 1299 },
  { name: 'Jeans', category: 'clothing', price: 79 }
];

// Agrupar por categoria
const groupedByCategory = products.groupBy(item => item.category);
console.log(groupedByCategory);
// {
//   electronics: [
//     { name: 'iPhone', category: 'electronics', price: 999 },
//     { name: 'Laptop', category: 'electronics', price: 1299 }
//   ],
//   clothing: [
//     { name: 'Shirt', category: 'clothing', price: 29 },
//     { name: 'Jeans', category: 'clothing', price: 79 }
//   ]
// }

// Agrupar por faixa de preço
const groupedByPrice = products.groupBy(item => 
  item.price > 100 ? 'expensive' : 'affordable'
);

2. Promise.withResolvers()

Criar promises com resolvers externos:

// Antes
function createDeferredPromise() {
  let resolve, reject;
  const promise = new Promise((res, rej) => {
    resolve = res;
    reject = rej;
  });
  return { promise, resolve, reject };
}

// Agora - ES2024
const { promise, resolve, reject } = Promise.withResolvers();

// Uso prático
class EventualValue {
  constructor() {
    this.#deferred = Promise.withResolvers();
  }
  
  get value() {
    return this.#deferred.promise;
  }
  
  setValue(value) {
    this.#deferred.resolve(value);
  }
  
  setError(error) {
    this.#deferred.reject(error);
  }
}

const eventualData = new EventualValue();

// Em algum lugar do código
setTimeout(() => {
  eventualData.setValue('Dados carregados!');
}, 2000);

// Em outro lugar
eventualData.value.then(data => console.log(data));

3. Temporal API (Preview)

Nova API para manipulação de datas:

// Dates mais precisas e timezone-aware
const now = Temporal.Now.plainDateTimeISO();
const birthday = Temporal.PlainDate.from('1990-05-15');

// Cálculos de data mais intuitivos
const age = now.toPlainDate().since(birthday, { unit: 'years' });
console.log(`Idade: ${age.years} anos`);

// Trabalhando com timezones
const meeting = Temporal.ZonedDateTime.from({
  year: 2024,
  month: 12,
  day: 25,
  hour: 10,
  timeZone: 'America/Sao_Paulo'
});

const meetingInTokyo = meeting.withTimeZone('Asia/Tokyo');
console.log(meetingInTokyo.toString());

4. String.dedent

Remove indentação de template strings:

function generateHTML(title, content) {
  return String.dedent`
    <article>
      <h1>${title}</h1>
      <div class="content">
        ${content}
      </div>
    </article>
  `;
}

const html = generateHTML('Meu Artigo', 'Conteúdo do artigo...');
// Retorna HTML sem indentação extra

5. Array.fromAsync()

Criar arrays de fontes assíncronas:

// Processar streams assíncronos
async function* fetchUserData() {
  const userIds = [1, 2, 3, 4, 5];
  
  for (const id of userIds) {
    const response = await fetch(`/api/users/${id}`);
    const user = await response.json();
    yield user;
  }
}

// Converter para array
const users = await Array.fromAsync(fetchUserData());
console.log(users); // Array com todos os usuários

// Com transformação
const userNames = await Array.fromAsync(
  fetchUserData(),
  user => user.name.toUpperCase()
);

6. Set methods

Novos métodos para Set:

const set1 = new Set([1, 2, 3, 4]);
const set2 = new Set([3, 4, 5, 6]);

// Interseção
const intersection = set1.intersection(set2);
console.log(intersection); // Set {3, 4}

// União
const union = set1.union(set2);
console.log(union); // Set {1, 2, 3, 4, 5, 6}

// Diferença
const difference = set1.difference(set2);
console.log(difference); // Set {1, 2}

// Diferença simétrica
const symmetricDifference = set1.symmetricDifference(set2);
console.log(symmetricDifference); // Set {1, 2, 5, 6}

// Verificar se é subconjunto
const subset = new Set([1, 2]);
console.log(subset.isSubsetOf(set1)); // true

// Verificar se é superconjunto
console.log(set1.isSupersetOf(subset)); // true

// Verificar se são disjuntos
const disjoint = new Set([7, 8]);
console.log(set1.isDisjointFrom(disjoint)); // true

7. RegExp v flag

Nova flag para expressões regulares mais poderosas:

// Suporte a propriedades Unicode
const emojiRegex = /\p{Emoji}/v;
console.log(emojiRegex.test('😀')); // true

// Operações de conjunto em caracteres
const asciiLetters = /[a-zA-Z]/v;
const digits = /[0-9]/v;

// Intersections, unions, subtractions
const alphanumeric = /[\p{Letter}&&\p{ASCII}]/v;
const nonDigits = /[^\p{Number}]/v;

8. Import attributes

Importar módulos com metadados:

// Importar JSON
import config from './config.json' with { type: 'json' };

// Importar CSS (em alguns ambientes)
import styles from './styles.css' with { type: 'css' };

// Importar WebAssembly
import wasmModule from './module.wasm' with { type: 'webassembly' };

// Verificar tipo durante import
if (import.meta.resolve) {
  const moduleUrl = import.meta.resolve('./module.js');
  const module = await import(moduleUrl, {
    with: { type: 'module' }
  });
}

9. Decorator support (Stage 3)

Decorators nativos no JavaScript:

// Decorator de classe
@logged
class UserService {
  @cache(60000) // Cache por 1 minuto
  async getUser(id) {
    return await fetch(`/api/users/${id}`).then(r => r.json());
  }
  
  @validate
  createUser(userData) {
    // Implementação
  }
}

// Implementação dos decorators
function logged(target) {
  return class extends target {
    constructor(...args) {
      super(...args);
      console.log(`${target.name} instance created`);
    }
  };
}

function cache(duration) {
  return function(target, propertyKey, descriptor) {
    const originalMethod = descriptor.value;
    const cache = new Map();
    
    descriptor.value = function(...args) {
      const key = JSON.stringify(args);
      
      if (cache.has(key)) {
        const cached = cache.get(key);
        if (Date.now() - cached.timestamp < duration) {
          return cached.value;
        }
      }
      
      const result = originalMethod.apply(this, args);
      cache.set(key, { value: result, timestamp: Date.now() });
      return result;
    };
  };
}

10. Pipeline operator (Preview)

Composição de funções mais legível:

// Sem pipeline
const result = Math.round(Math.abs(Math.sqrt(16)));

// Com pipeline operator
const result = 16
  |> Math.sqrt
  |> Math.abs
  |> Math.round;

// Uso mais complexo
const processUserData = (userData) =>
  userData
    |> validateUser
    |> normalizeData
    |> enrichWithMetadata
    |> saveToDatabase;

// Com arrow functions
const users = await fetch('/api/users')
  |> (response => response.json())
  |> (data => data.filter(user => user.active))
  |> (users => users.map(user => ({ ...user, processed: true })));

Casos de uso práticos

Data processing pipeline

const processAnalytics = (rawData) =>
  rawData
    |> (data => data.filter(item => item.valid))
    |> (data => data.groupBy(item => item.category))
    |> (grouped => Object.entries(grouped))
    |> (entries => entries.map(([category, items]) => ({
        category,
        count: items.length,
        revenue: items.reduce((sum, item) => sum + item.revenue, 0)
      })))
    |> (results => results.sort((a, b) => b.revenue - a.revenue));

Form validation

@validateOnSubmit
class ContactForm {
  @required
  @email
  email = '';
  
  @required
  @minLength(3)
  name = '';
  
  @required
  @minLength(10)
  message = '';
}

Conclusão

O ES2024 continua tornando o JavaScript mais expressivo e poderoso. Essas funcionalidades vão gradualmente sendo implementadas pelos navegadores e engines, então fique atento ao suporte antes de usar em produção.

As novidades mostram que o JavaScript está evoluindo para ser mais funcional, mais expressivo e mais adequado para aplicações modernas complexas.

Ricardo Laurito

Sobre o Autor

UI/UX Designer e Desenvolvedor Web especializado em React e Next.js

Comentários

0 Comentários

Seja o primeiro a comentar neste artigo.