JavaScript de 2022 a 2026: cinco años de evolución que han cambiado nuestra forma de programar

JavaScript de 2022 a 2026: cinco años de evolución que han cambiado nuestra forma de programar

Hace ya unos años publiqué en este blog una entrada dedicada a las novedades de JavaScript en 2021. En aquel momento repasábamos algunas de las características que se habían incorporado al lenguaje y cómo, poco a poco, JavaScript seguía evolucionando para facilitarnos el trabajo.

Desde entonces han pasado cinco años y, aunque he seguido trabajando con JavaScript en diferentes proyectos, tenía pendiente volver a dedicarle una entrada a su evolución.

Y lo cierto es que, al ponerme a revisar todo lo que ha cambiado desde aquella publicación, me he dado cuenta de que hay mucho más que contar de lo que inicialmente pensaba.

JavaScript no es exactamente el mismo lenguaje que utilizábamos hace cinco años. Aunque su sintaxis fundamental sigue siendo reconocible, se han incorporado numerosas funcionalidades que han transformado la manera en que trabajamos con arrays, objetos, promesas, clases, iteradores y estructuras de datos.

Muchas operaciones que antes necesitaban funciones auxiliares, librerías externas o varias líneas de código ahora pueden resolverse utilizando características nativas del propio lenguaje.

Y esto es algo que me parece especialmente interesante: muchas veces seguimos programando de una determinada manera simplemente porque es como hemos aprendido a hacerlo. Sin embargo, el lenguaje continúa avanzando y algunas de esas soluciones que llevamos años utilizando ya tienen alternativas más sencillas.

Por eso he querido recuperar el hilo de aquella publicación de 2021 y continuar donde lo dejamos, repasando las novedades que han ido llegando con ECMAScript 2022, 2023, 2024, 2025 y 2026.

La intención es la misma que entonces: explicar los cambios de una forma práctica, entender para qué sirven y ver cómo podemos aprovecharlos en nuestros proyectos, sin limitarnos a enumerar nuevas funcionalidades.

Porque, al final, conocer las novedades de JavaScript no consiste únicamente en escribir código más moderno, sino en descubrir nuevas formas de resolver los problemas cotidianos del desarrollo.

JavaScript y ECMAScript: ¿son lo mismo?

Antes de comenzar, conviene aclarar una diferencia que, aunque pueda parecer básica, todavía genera cierta confusión.

JavaScript es el lenguaje de programación que utilizamos habitualmente en navegadores, aplicaciones web y servidores. ECMAScript es la especificación que define su núcleo: sintaxis, tipos de datos, objetos integrados y comportamiento del lenguaje.

Su evolución está coordinada por TC39, el comité técnico responsable de desarrollar nuevas propuestas y llevarlas hasta su estandarización.

Desde 2015, ECMAScript publica ediciones anuales.

Esto significa que no necesitamos esperar varios años para recibir una gran actualización. Las funcionalidades se incorporan progresivamente cuando alcanzan la madurez necesaria.

También conviene recordar que una característica incluida en una edición de ECMAScript no tiene por qué estar disponible inmediatamente en todos los navegadores o versiones de Node.js. Cada motor JavaScript incorpora las novedades siguiendo su propio calendario.

Con esto claro, vamos a recorrer los cambios más interesantes de estos cinco años.

ECMAScript 2022: clases más completas y nuevas herramientas

ECMAScript 2022, también conocido como ES13, introdujo mejoras importantes en la programación orientada a objetos y el manejo de módulos.

Una de las más relevantes fue la consolidación de los elementos privados en las clases.

Propiedades privadas de verdad

Durante muchos años, JavaScript no tenía una forma nativa de declarar atributos verdaderamente privados.

Aunque existían convenciones como anteponer un guion bajo al nombre de una propiedad, no impedían su acceso desde el exterior.

Con ES2022 llegaron los campos privados identificados mediante #.

class CuentaBancaria { 
   #saldo = 0;
   ingresar(cantidad) {
      this.#saldo += cantidad; 
   } 
   consultarSaldo() {
      return this.#saldo;
   }
}

const cuenta = new CuentaBancaria();
cuenta.ingresar(100);
console.log(cuenta.consultarSaldo()); // 100

Ahora, intentar acceder a cuenta.#saldo desde fuera de la clase provoca un error de sintaxis.

Las clases también incorporaron campos públicos, métodos y accesores privados, elementos estáticos privados y bloques de inicialización static.

Estas funcionalidades permiten trabajar con clases mejor encapsuladas, sin depender exclusivamente de convenciones entre desarrolladores.

Acceder al último elemento con at()

Una de las novedades más sencillas, pero también más cómodas:

const frutas = ["manzana", "pera", "naranja"];
console.log(frutas.at(-1)); // naranja

Anteriormente, una forma habitual de conseguirlo era:

frutas[frutas.length - 1];

El método at() funciona también con cadenas de texto y arrays tipados.

Puede parecer una mejora pequeña, pero cuando trabajamos constantemente con colecciones, este tipo de incorporaciones terminan haciendo que el código sea más legible.

Await fuera de funciones asíncronas

ES2022 permitió utilizar await directamente en el nivel superior de un módulo.

const respuesta = await fetch("/api/productos");
const productos = await respuesta.json();
console.log(productos);

Esto simplifica determinados procesos de inicialización, aunque hay que tener en cuenta que puede afectar a la evaluación de los módulos dependientes.

No significa que podamos utilizar await en cualquier lugar: esta funcionalidad está pensada para módulos JavaScript.

Object.hasOwn(): comprobar propiedades propias

Otra incorporación interesante fue Object.hasOwn().

const usuario = { nombre: "Ana", edad: 25 };
console.log(Object.hasOwn(usuario, "nombre")); // true
console.log(Object.hasOwn(usuario, "email")); // false

Permite comprobar si una propiedad pertenece directamente al objeto, sin confundirla con propiedades heredadas de su prototipo.

Error.cause: conservar el origen de los errores

Cuando una operación falla, en ocasiones capturamos el error original y lanzamos otro más descriptivo.

ES2022 permitió conservar la causa original mediante la propiedad cause.

try {
   JSON.parse("{incorrecto}");
} catch (error) {
   throw new Error("Configuración inválida", { cause: error });
}

Esto resulta especialmente útil para depurar aplicaciones y mantener información sobre el origen de un problema.

Índices de coincidencias en expresiones regulares

La bandera /d permite obtener las posiciones donde se producen las coincidencias.

const resultado = /JavaScript/d.exec( "Aprende JavaScript" );
console.log(resultado.indices[0]); // [8, 18]

Puede resultar útil en editores, analizadores de texto y aplicaciones que necesitan localizar fragmentos concretos de una cadena.

En conjunto, ES2022 nos proporcionó clases más completas, mejores herramientas de encapsulación y pequeñas mejoras que simplificaron operaciones habituales.

ECMAScript 2023: trabajar con arrays sin modificar los originales

Si utilizas Vue, React o cualquier sistema basado en estados reactivos, seguramente una de las novedades que más te interesa de ES2023 sea la incorporación de métodos no mutables para arrays.

Tradicionalmente, muchas operaciones modificaban directamente el array sobre el que trabajábamos.

Por ejemplo:

const numeros = [4, 1, 3, 2];
numeros.sort();
console.log(numeros); // [1, 2, 3, 4]

El problema es que sort() modifica el array original.

En determinadas arquitecturas, especialmente cuando queremos conservar el estado anterior, este comportamiento puede resultar incómodo.

toSorted(): ordenar sin modificar

ES2023 incorporó toSorted().

const numeros = [4, 1, 3, 2];
const ordenados = numeros.toSorted();
console.log(ordenados); // [1, 2, 3, 4]
console.log(numeros); // [4, 1, 3, 2]

En lugar de modificar el array original, devuelve uno nuevo.

Esto facilita el tratamiento de datos cuando no queremos alterar directamente las estructuras existentes.

toReversed(): invertir sin mutación

Algo parecido ocurre con reverse() que también modifica el array sobre el que se ejecuta.

Ahora podemos utilizar:

const letras = ["A", "B", "C"];
const invertidas = letras.toReversed();
console.log(invertidas); // ["C", "B", "A"]
console.log(letras); // ["A", "B", "C"]

De nuevo, obtenemos el resultado sin alterar los valores originales.

toSpliced(): insertar y eliminar elementos

El método splice() es útil, pero también modifica el array.

Con toSpliced() podemos realizar operaciones similares obteniendo una nueva colección.

const numeros = [10, 20, 30, 40];
const resultado = numeros.toSpliced(1, 2);
console.log(resultado); // [10, 40]
console.log(numeros); // [10, 20, 30, 40]

with(): sustituir elementos

Este método permite reemplazar un elemento de un array sin modificar el original.

const colores = ["rojo", "verde", "azul"];
const nuevosColores = colores.with( 1, "amarillo" );
console.log(nuevosColores); // ["rojo", "amarillo", "azul"]
console.log(colores); // ["rojo", "verde", "azul"]

Resulta especialmente cómodo cuando necesitamos actualizar una posición concreta de una colección.

findLast() y findLastIndex()

Estas dos funciones permiten buscar comenzando desde el final del array.

const edades = [18, 25, 32, 21, 40];
const ultima = edades.findLast( edad => edad < 30 );
console.log(ultima); // 21

findLastIndex() realiza una búsqueda equivalente, pero devuelve la posición del último elemento que cumple la condición.

const edades = [18, 25, 32, 21, 40];
const indice = edades.findLastIndex( edad => edad < 30 );
console.log(indice); // 3

Esto evita tener que invertir manualmente el array o recorrerlo desde el final mediante un bucle.

Otras incorporaciones de ES2023

ES2023 también estandarizó los comentarios hashbang (#!), utilizados para indicar el intérprete de determinados scripts ejecutables.

Además, amplió las posibilidades de utilizar símbolos no registrados como claves en WeakMap y elementos en WeakSet.

La idea central de ES2023 fue facilitar el trabajo con datos sin modificar accidentalmente las estructuras originales.

Y, personalmente, considero que esta ha sido una de las actualizaciones más prácticas para quienes trabajamos habitualmente con interfaces y estados reactivos.

ECMAScript 2024: agrupar datos nunca había sido tan sencillo

La edición de 2024 incorporó funciones especialmente interesantes para aplicaciones que trabajan con colecciones y operaciones asíncronas.

Object.groupBy(): agrupar sin reduce()

Imaginemos una aplicación de comercio electrónico que necesita agrupar productos por categorías.

Antes era habitual resolverlo mediante reduce() o funciones auxiliares.

Ahora podemos escribir:

const productos = [
   { nombre: "Manzana", categoria: "fruta" },
   { nombre: "Pera", categoria: "fruta" },
   { nombre: "Zanahoria", categoria: "verdura" }
]; 
const agrupados = Object.groupBy( productos, producto => producto.categoria ); 
console.log(agrupados.fruta);

El resultado contiene las agrupaciones correspondientes.

Esta funcionalidad resulta útil en paneles de administración, estadísticas, informes y aplicaciones que necesitan transformar datos procedentes de una API.

Por ejemplo, podemos agrupar usuarios por rol, pedidos por estado o registros por categoría sin tener que implementar manualmente toda la lógica.

Map.groupBy(): agrupaciones con claves más flexibles

También existe Map.groupBy() especialmente interesante cuando las claves de agrupación no son simples cadenas de texto.

const usuarios = [
   { nombre: "Ana", activo: true },
   { nombre: "Luis", activo: false },
   { nombre: "Eva", activo: true }
];
const grupos = Map.groupBy( usuarios, usuario => usuario.activo );
console.log(grupos.get(true));

En este caso, el resultado es un Map, lo que permite utilizar claves de diferentes tipos conservando su identidad.

Promise.withResolvers(): promesas más cómodas

Otra incorporación fue Promise.withResolvers().

const { promise, resolve, reject } = Promise.withResolvers();
setTimeout(() => {
   resolve("Operación completada");
}, 1000);
console.log(await promise);

Antes, cuando necesitábamos separar la promesa de sus funciones resolve y reject, era habitual recurrir a un patrón algo más elaborado.

Ahora JavaScript proporciona directamente los tres elementos.

Esto facilita determinadas integraciones con sistemas basados en eventos o procesos asíncronos.

Unicode y expresiones regulares

ES2024 incorporó también nuevos métodos para trabajar con cadenas Unicode.

Con isWellFormed() podemos comprobar si una cadena está bien formada según las reglas de UTF-16.

const texto = "Hola mundo";
console.log(texto.isWellFormed()); // true

Por su parte, toWellFormed() permite obtener una cadena con los sustitutos Unicode aislados reemplazados por el carácter de sustitución correspondiente.

También llegó la bandera /v para expresiones regulares con conjuntos Unicode avanzados.

Esto amplía las posibilidades de trabajar con caracteres y secuencias Unicode, incluyendo operaciones como intersecciones y diferencias entre conjuntos.

Mejoras en ArrayBuffer y memoria compartida

ES2024 añadió mecanismos para redimensionar y transferir ArrayBuffer, ampliar determinados SharedArrayBuffer y utilizar Atomics.waitAsync().

Estas funcionalidades son especialmente relevantes para aplicaciones que realizan procesamiento binario o trabajan con memoria compartida.

Aunque posiblemente no sean novedades que utilicemos todos los días en una aplicación web convencional, ofrecen nuevas posibilidades para tareas más especializadas.

ES2024 destacó por simplificar agrupaciones y ampliar las herramientas de programación asíncrona y procesamiento de datos.

ECMAScript 2025: una nueva manera de trabajar con colecciones

ES2025 supuso una mejora significativa en el tratamiento de iteradores y conjuntos.

Algunas de sus nuevas herramientas permiten escribir operaciones que antes necesitaban conversiones intermedias o implementaciones manuales.

Iterator Helpers: transformar datos de forma diferida

Imaginemos que tenemos una colección de números y necesitamos filtrar, transformar y limitar los resultados.

const numeros = [1, 2, 3, 4, 5, 6];
const resultado = Iterator.from(numeros).filter(numero => numero % 2 === 0).map(numero => numero * 10).take(2).toArray();
console.log(resultado); // [20, 40]

Lo interesante es que los iteradores pueden procesar elementos de manera diferida.

Esto evita crear necesariamente un array intermedio después de cada transformación.

Los nuevos métodos incluyen map(), filter(), take(), drop(), flatMap(), reduce(), forEach(), some(), every(), find() y toArray().

Esta forma de trabajar resulta especialmente interesante cuando tenemos grandes colecciones de datos o queremos encadenar transformaciones de una manera más expresiva.

Nuevas operaciones con Set

JavaScript también incorporó operaciones habituales de teoría de conjuntos.

const grupoA = new Set([1, 2, 3]);
const grupoB = new Set([3, 4, 5]);
console.log([...grupoA.union(grupoB)]); // [1, 2, 3, 4, 5]
console.log([...grupoA.intersection(grupoB)]); // [3]
console.log([...grupoA.difference(grupoB)]); // [1, 2]

Ahora tenemos métodos nativos para obtener uniones, intersecciones, diferencias, diferencias simétricas y comprobar relaciones entre conjuntos.

Pensemos, por ejemplo, en una aplicación de usuarios y permisos: podemos determinar qué permisos tienen en común dos roles o qué permisos son exclusivos de uno de ellos.

También podemos comprobar si un conjunto es subconjunto de otro o si dos conjuntos no tienen elementos comunes.

const permisosUsuario = new Set([ "leer", "editar" ]);
const permisosAdmin = new Set([ "leer", "editar", "eliminar" ]);
console.log(permisosUsuario.isSubsetOf(permisosAdmin)); // true

Lo que antes nos obligaba a realizar comparaciones manuales ahora puede resolverse mediante métodos nativos.

RegExp.escape(): construir expresiones regulares con seguridad

Cuando una búsqueda incorpora texto procedente del usuario, ciertos caracteres pueden tener un significado especial dentro de una expresión regular.

ES2025 incorporó RegExp.escape() para escapar adecuadamente ese texto.

const busqueda = "producto (nuevo)";
const regex = new RegExp( RegExp.escape(busqueda), "i" );
console.log(regex.test("Producto (nuevo)")); // true

Es una mejora de seguridad y robustez para la construcción dinámica de expresiones regulares, aunque no sustituye la validación de entradas en otros contextos.

Promise.try(): unificar código síncrono y asíncrono

Otra mejora interesante es Promise.try().

const resultado = Promise.try(() => {
   return JSON.parse('{"activo":true}');
});
console.log(await resultado);

Independientemente de que la función devuelva un valor, una promesa o lance un error, podemos trabajar con un resultado de tipo promesa.

Esto permite mantener un tratamiento más uniforme de determinadas operaciones.

Importaciones JSON con atributos

ES2025 también estandarizó la utilización de atributos de importación, incluyendo la importación de módulos JSON.

import configuracion from "./config.json" with { type: "json" };
console.log(configuracion);

De esta forma, podemos indicar explícitamente el tipo de recurso que queremos importar.

La compatibilidad y las condiciones de uso dependen del entorno JavaScript en el que se ejecute el código.

Otras novedades de ES2025

También llegaron las expresiones regulares con modificadores dentro de grupos y nuevas herramientas numéricas como Float16Array, Math.f16round() y los métodos correspondientes de  DataView.

Estas últimas incorporaciones permiten trabajar con valores de coma flotante de 16 bits, algo especialmente interesante en determinados escenarios de procesamiento gráfico, datos binarios y aplicaciones especializadas.

Con ES2025, JavaScript dio un paso importante hacia una manipulación más expresiva de las colecciones y los flujos de datos.

ECMAScript 2026: precisión, asincronía y menos código repetitivo

ECMAScript 2026, la decimoséptima edición del estándar, continúa incorporando funcionalidades que simplifican operaciones habituales y amplían las posibilidades del lenguaje.

Esta edición introduce mejoras que parecen pequeñas por separado, pero solucionan problemas frecuentes en el desarrollo cotidiano.

Array.fromAsync(): construir arrays desde fuentes asíncronas

Hasta ahora, convertir un iterable asíncrono en un array requería implementar un recorrido o utilizar una función auxiliar.

Con Array.fromAsync() resulta mucho más sencillo.

async function* obtenerValores() {
  yield 10;
  yield 20;
  yield 30;
}

const valores = await Array.fromAsync(
  obtenerValores()
);

console.log(valores); // [10, 20, 30]

Puede ser especialmente útil para transformar fuentes asíncronas de datos en colecciones.

Hay que recordar, eso sí, que el resultado completo termina almacenado en memoria.

Math.sumPrecise(): una suma más precisa

Los números de coma flotante presentan limitaciones conocidas.

Por ejemplo:

const numeros = [1e17, 1, -1e17];

console.log(
  numeros.reduce((a, b) => a + b, 0)
);
// 0

Matemáticamente, el resultado debería ser 1, pero durante las operaciones se pierde precisión.

Con Math.sumPrecise() podemos utilizar una operación diseñada para reducir ese problema:

console.log(Math.sumPrecise(numeros));
// 1

Esta función está diseñada para reducir los errores de redondeo acumulados al sumar números de distinta magnitud.

No significa que JavaScript haya resuelto todos los problemas numéricos ni que sustituya a una librería decimal cuando necesitamos aritmética decimal exacta.

Map.getOrInsert(): recuperar o insertar

Una operación bastante habitual con Map consiste en comprobar si existe una clave y crear un valor inicial cuando falta.

Ahora podemos hacerlo directamente:

const visitas = new Map();

visitas.getOrInsert("inicio", 0);

console.log(visitas.get("inicio"));
// 0

Además, getOrInsertComputed() permite calcular el valor solamente cuando la clave todavía no existe.

const cache = new Map();

const usuario = cache.getOrInsertComputed(
  "usuario-1",
  () => ({
    nombre: "Ana",
    activo: true
  })
);

Estas operaciones también tienen equivalentes para WeakMap.

Son métodos interesantes para la implementación de cachés y estructuras que necesitan valores iniciales.

Iterator.concat(): unir iterables

Otra incorporación permite concatenar diferentes iterables mediante Iterator.concat().

const resultado = Iterator.concat(
  [1, 2],
  new Set([3, 4]),
  [5, 6]
);

console.log(resultado.toArray());
// [1, 2, 3, 4, 5, 6]

La diferencia respecto a concatenar arrays es que trabajamos directamente con iterables y podemos aprovechar la evaluación diferida.

Error.isError(): reconocer errores

ES2026 incorpora también una función específica para comprobar si un valor es un objeto de error.

try {
  throw new TypeError("Dato incorrecto");
} catch (error) {
  console.log(Error.isError(error));
  // true
}

Esta función proporciona una comprobación específica para objetos de error, incluso en escenarios donde instanceof Error presenta limitaciones, como al trabajar entre diferentes contextos de ejecución.

Base64 y hexadecimal directamente con Uint8Array

ES2026 incorpora funciones para convertir datos binarios entre bytes, Base64 y hexadecimal.

const bytes = new Uint8Array([72, 111, 108, 97]);

const base64 = bytes.toBase64();

console.log(base64); // SG9sYQ==

const recuperados = Uint8Array.fromBase64(base64);

También contamos con métodos equivalentes para trabajar con representaciones hexadecimales.

const bytes = new Uint8Array([72, 111, 108, 97]);

console.log(bytes.toHex());
// 486f6c61

const recuperados = Uint8Array.fromHex(
  "486f6c61"
);

Esto facilita la manipulación de datos binarios sin depender de conversiones indirectas.

Mayor control sobre JSON

La edición también incorpora funcionalidades para conservar o utilizar la representación textual original de determinados valores JSON.

Por ejemplo:

const datos = JSON.parse(
  '{"id":9007199254740993}',
  (clave, valor, contexto) => {
    if (clave === "id") {
      return BigInt(contexto.source);
    }

    return valor;
  }
);

console.log(datos.id);
// 9007199254740993n

Además, JSON.rawJSON() y JSON.isRawJSON() permiten trabajar con valores JSON primitivos representados mediante su texto original.

Son herramientas especialmente interesantes cuando debemos preservar datos numéricos que exceden la precisión segura de Number.

ES2026 continúa la tendencia de los últimos años: simplificar operaciones frecuentes y ofrecer herramientas más especializadas sin depender necesariamente de implementaciones externas.

¿Qué novedades merecen realmente la pena?

Después de repasar cinco años de evolución, es lógico preguntarse cuáles de estas funcionalidades merece la pena incorporar a nuestros proyectos.

Y lo cierto es que no todas tienen el mismo impacto en el desarrollo diario.

Para quienes trabajamos habitualmente creando aplicaciones web, estas son algunas de las más interesantes:

Funcionalidad Versión Utilidad
at() ES2022 Acceso cómodo a elementos
Campos privados # ES2022 Encapsulación de clases
toSorted() y toReversed() ES2023 Operaciones sin mutación
toSpliced() y with() ES2023 Modificación inmutable de arrays
Object.groupBy() ES2024 Agrupación de datos
Promise.withResolvers() ES2024 Gestión de promesas
Iterator Helpers ES2025 Transformaciones diferidas
Operaciones de Set ES2025 Comparación de colecciones
RegExp.escape() ES2025 Construcción segura de RegExp
Promise.try() ES2025 Normalización de operaciones
Array.fromAsync() ES2026 Colecciones asíncronas
Map.getOrInsert() ES2026 Gestión de valores por defecto
Math.sumPrecise() ES2026 Sumas numéricas más precisas

Probablemente, las mejoras más fáciles de incorporar al código existente sean los métodos no mutables de arrays, las operaciones de agrupación y las nuevas funcionalidades de Set.

No necesitan transformar completamente nuestra arquitectura y pueden simplificar considerablemente determinadas funciones.

Por ejemplo, cuando trabajamos con Vue o React, disponer de métodos que devuelven nuevas colecciones sin modificar las originales resulta especialmente cómodo.

En aplicaciones que procesan información procedente de APIs, Object.groupBy() también puede ayudarnos a eliminar bastante código repetitivo.

Y en sistemas que manejan permisos, categorías o identificadores únicos, las operaciones nativas de  Se resultan muy prácticas.

Al final, lo interesante no es utilizar todas las funcionalidades nuevas, sino saber que existen y reconocer cuándo nos pueden ahorrar trabajo.

¿Podemos utilizar todas estas novedades en producción?

Aquí aparece una diferencia importante: que una característica forme parte del estándar ECMAScript no significa que esté disponible en todos los navegadores o entornos de ejecución.

Cada motor JavaScript incorpora las funcionalidades siguiendo su propio calendario.

Por eso debemos distinguir entre:

  • Estandarización de la característica.
  • Compatibilidad del navegador o de Node.js.
  • Versiones del motor JavaScript incluido en Electron.
  • Disponibilidad de polyfills.
  • Posibilidad de transformar sintaxis mediante herramientas de compilación.

Por ejemplo, una aplicación construida con Vue y Vite puede utilizar determinadas funcionalidades modernas durante el desarrollo, pero eso no garantiza su ejecución en un navegador antiguo.

Además, los polyfills no resuelven automáticamente todas las diferencias de comportamiento ni todas las nuevas construcciones sintácticas.

Antes de utilizar características recientes en aplicaciones destinadas a producción conviene revisar su compatibilidad y las versiones mínimas que necesitamos soportar.

Personalmente, considero que es preferible incorporar estas novedades de forma progresiva y conociendo bien su comportamiento, en lugar de intentar utilizar siempre la última característica disponible simplemente porque es nueva.

La estabilidad y la compatibilidad de una aplicación siguen siendo tan importantes como la modernidad de su código.

¿Y qué viene después de 2026?

JavaScript continúa evolucionando.

Entre las funcionalidades que han avanzado en TC39 y que no pertenecen a la edición de ES2026 destacan dos especialmente interesantes.

Temporal: una nueva manera de trabajar con fechas

Durante años, trabajar con fechas y zonas horarias ha sido una de las partes más incómodas de JavaScript.

La API Date tiene limitaciones conocidas, especialmente cuando necesitamos manejar calendarios, zonas horarias y operaciones complejas.

Temporal propone una API más completa y consistente para trabajar con fechas y horas.

Su objetivo es resolver muchos de esos problemas sin necesidad de recurrir siempre a soluciones externas.

Explicit Resource Management: gestionar mejor los recursos

Otra propuesta introduce construcciones como using y await using.

Estas permiten gestionar la liberación de determinados recursos de forma estructurada.

La idea es facilitar que recursos como conexiones, manejadores o estructuras que requieren limpieza puedan liberarse de manera más predecible.

También continúan desarrollándose nuevas operaciones sobre iteradores y otras mejoras del lenguaje.

Estas propuestas muestran hacia dónde se dirige JavaScript: mejores herramientas integradas y menos necesidad de repetir patrones que aparecen una y otra vez en nuestras aplicaciones.

Conclusión: JavaScript ha cambiado mucho más de lo que parece

Cuando observamos las novedades individualmente, algunas pueden parecer incorporaciones menores.

Un nuevo método para ordenar un array, otro para agrupar objetos o una función adicional para trabajar con promesas.

Sin embargo, al analizar los cinco años en conjunto, la evolución resulta mucho más significativa.

Entre 2022 y 2026, JavaScript se ha convertido en un lenguaje más cómodo para trabajar con datos, más completo para desarrollar clases y mejor equipado para resolver operaciones asíncronas y manipular colecciones.

Muchas tareas que tradicionalmente necesitaban código auxiliar ahora cuentan con soluciones estandarizadas.

Esto no significa que debamos actualizar nuestras aplicaciones para utilizar cada funcionalidad nueva inmediatamente, ni que el código moderno sea siempre mejor simplemente por emplear la sintaxis más reciente.

Lo importante es conocer las herramientas disponibles, comprender qué problemas solucionan y decidir cuándo aportan realmente valor.

Y volviendo al comienzo de este artículo, cuando publiqué aquella entrada sobre las novedades de JavaScript en 2021, muchas de las funcionalidades que hemos repasado hoy todavía no formaban parte del estándar.

Cinco años después, algunas se han convertido en herramientas habituales y otras apenas están empezando a llegar a nuestros proyectos.

Lo curioso es que seguramente dentro de unos años volveremos a encontrarnos en una situación parecida: revisando código que hoy consideramos moderno y descubriendo que el lenguaje ya ofrece nuevas formas de hacer lo mismo.

Y precisamente eso es lo que me sigue resultando interesante del desarrollo web.

Por mucho tiempo que llevemos programando, siempre quedan cosas nuevas por aprender, herramientas por descubrir y formas de mejorar lo que hacemos.

Porque aprender JavaScript moderno no consiste únicamente en memorizar nuevos métodos.

Consiste en descubrir que problemas que llevamos años resolviendo de una determinada manera ahora pueden tener soluciones más sencillas, expresivas y mantenibles.

Así que, con esta publicación, retomamos aquella entrada de 2021 y dejamos actualizado nuestro recorrido por JavaScript hasta 2026.

Veremos qué nos deparan las próximas versiones.

Referencias y documentación

Para quienes quieran profundizar en las novedades o consultar directamente las especificaciones oficiales, estas son algunas de las fuentes más interesantes: