ECMAScript 2024: evolucion pragmatica
La especificacion ECMAScript 2024 (ES15) fue aprobada oficialmente en junio de 2024 y trae funcionalidades que muchos desarrolladores llevaban pidiendo durante años. A diferencia de versiones anteriores que se centraban en sintaxis, ES2024 se enfoca en utilidades prácticas que simplifican el código del dia a dia.
Object.groupBy() y Map.groupBy()
Sin duda, la estrella de ES2024. Object.groupBy() permite agrupar elementos de un iterable usando una función clasificadora.
Antes vs. Ahora
// ANTES: agrupacion manual con reduce
const porCategoria = productos.reduce((acc, producto) => {
const key = producto.categoria;
if (!acc[key]) acc[key] = [];
acc[key].push(producto);
return acc;
}, {});
// AHORA: una sola linea
const porCategoria = Object.groupBy(productos, p => p.categoria);Map.groupBy() para claves no-string
Cuando necesitas claves que no son strings (objetos, números, etc.), usa Map.groupBy():
const usuarios = [
{ nombre: 'Ana', edad: 25 },
{ nombre: 'Carlos', edad: 17 },
{ nombre: 'Diana', edad: 30 },
{ nombre: 'Luis', edad: 15 },
];
const porMayoriaEdad = Map.groupBy(usuarios, u =>
u.edad >= 18 ? 'adulto' : 'menor'
);
// Map { 'adulto' => [...], 'menor' => [...] }Consideraciones importantes
Object.groupBy()crea un objeto sin prototipo (Object.create(null))- Las claves se convierten a string (como en objetos normales)
- Para claves complejas, usa
Map.groupBy() - El iterable original no se modifica
Promise.withResolvers()
Este nuevo método estático simplifica un patrón muy comun: crear una Promise y extraer sus funciones resolve y reject.
// ANTES: patrón comun pero verboso
let resolve, reject;
const promise = new Promise((res, rej) => {
resolve = res;
reject = rej;
});
// AHORA: limpio y directo
const { promise, resolve, reject } = Promise.withResolvers();Caso de uso real: encapsular un EventEmitter
function esperarEvento(emitter, evento) {
const { promise, resolve, reject } = Promise.withResolvers();
emitter.addEventListener(evento, resolve, { once: true });
emitter.addEventListener('error', reject, { once: true });
return promise;
}
// Uso
const resultado = await esperarEvento(socket, 'message');ArrayBuffer resizable y transferible
ES2024 introduce ArrayBuffer con tamaño ajustable y la capacidad de transferir ownership entre contextos.
ArrayBuffer resizable
// Crear un buffer que puede crecer hasta 1MB
const buffer = new ArrayBuffer(256, { maxByteLength: 1024 * 1024 });
console.log(buffer.byteLength); // 256
console.log(buffer.maxByteLength); // 1048576
console.log(buffer.resizable); // true
// Redimensionar
buffer.resize(512);
console.log(buffer.byteLength); // 512Transferencia de ArrayBuffer
const original = new ArrayBuffer(1024);
const view = new Uint8Array(original);
view[0] = 42;
// Transferir a un nuevo buffer
const transferido = original.transfer();
console.log(original.byteLength); // 0 (desvinculado)
console.log(transferido.byteLength); // 1024
console.log(new Uint8Array(transferido)[0]); // 42Esto es especialmente útil al comunicarse con Web Workers, eliminando la necesidad de copiar datos.
String.isWellFormed() y String.toWellFormed()
JavaScript permite strings con surrogate pairs incompletos, lo cual puede causar problemas al interactuar con APIs como encodeURIComponent(). Estos nuevos métodos resuelven eso.
const texto = 'Hola \uD800 mundo'; // surrogate suelto
console.log(texto.isWellFormed()); // false
const textoCorregido = texto.toWellFormed();
console.log(textoCorregido.isWellFormed()); // true
// Reemplaza surrogates sueltos con U+FFFD (caracter de reemplazo)Cuando usarlos?
- Antes de enviar strings a APIs externas
- Al procesar datos de fuentes no confiables
- Al usar
TextEncoderoencodeURIComponent()
Atomics.waitAsync()
Una versión asincrona de Atomics.wait() que no bloquea el hilo principal:
const sharedBuffer = new SharedArrayBuffer(4);
const sharedArray = new Int32Array(sharedBuffer);
// No bloquea el hilo principal
const resultado = Atomics.waitAsync(sharedArray, 0, 0);
if (resultado.async) {
resultado.value.then(status => {
console.log('Worker notificado:', status);
});
}
// En otro Worker:
Atomics.store(sharedArray, 0, 1);
Atomics.notify(sharedArray, 0);RegExp v flag (unicodeSets)
El nuevo flag v extiende las capacidades de las expresiones regulares con conjuntos de caracteres Unicode:
// Buscar emojis (con flag v)
const emojiRegex = /\p{RGI_Emoji}/v;
console.log(emojiRegex.test('hola')); // false
// Interseccion de conjuntos: letras griegas que sean mayusculas
const regex = /[\p{Script=Greek}&&\p{Lu}]/v;
console.log(regex.test('A')); // false (latina)
// Diferencia de conjuntos: letras excepto vocales
const consonantes = /[\p{Letter}--[aeiouAEIOU]]/v;Operaciones de conjuntos con el flag v
| Operacion | Sintaxis | Descripcion |
|---|---|---|
| Union | [AB] |
A o B |
| Interseccion | [A&&B] |
A y B |
| Diferencia | [A--B] |
A pero no B |
Tabla resumen de soporte
| Funcionalidad | Chrome | Firefox | Safari | Node.js |
|---|---|---|---|---|
| Object.groupBy | 117+ | 119+ | 17.4+ | 21+ |
| Promise.withResolvers | 119+ | 121+ | 17.4+ | 22+ |
| ArrayBuffer.transfer | 114+ | 122+ | 17.4+ | 22+ |
| String.isWellFormed | 111+ | 119+ | 16.4+ | 20+ |
| Atomics.waitAsync | 87+ | 128+ | 16.4+ | 16+ |
| RegExp v flag | 112+ | 116+ | 17+ | 20+ |
Conclusion
ES2024 trae mejoras que, aunque no son tan llamativas como los arrow functions o async/await, resuelven fricciones reales del desarrollo diario. Object.groupBy() y Promise.withResolvers() en particular van a cambiar la forma en que escribimos JavaScript. Lo mejor: ya tienen soporte amplio en todos los navegadores modernos. Es hora de adoptarlos.



Comentarios (0)
Inicia sesión para comentar