ECMAScript es la especificación donde se mencionan todos los detalles de cómo debe funcionar y comportarse Javascript. De esta forma, los diferentes navegadores (Chrome, Firefox, Opera, Edge, Safari...) saben como deben desarrollar los motores de Javascript para que cualquier código o programa funcione exactamente igual, independientemente del navegador que se utilice.
ECMAScript suele venir acompañado de un número que indica la versión o revisión de la que hablamos (algo similar a las versiones de un programa). En cada nueva versión de ECMAScript, se añaden nuevas funcionalidades, manteniendo Javascript vivo y con novedades que lo hacen un lenguaje de programación moderno y cada vez mejor preparado.
Teniendo esto en cuenta, debemos saber que los navegadores web intentan cumplir la especificación ECMAScript al máximo, pero no todos ellos lo consiguen. Por lo tanto, pueden existir ciertas discrepancias. Por ejemplo, pueden existir navegadores que cumplan la especificación ECMAScript al 80% y otros que sólo la cumplan al 60%. Esto significa que pueden haber características que no funcionen en un navegador específico (y en otros sí).
Además, todo esto va cambiando a medida que se van lanzando nuevas versiones de los navegadores web, donde su compatibilidad ECMAScript suele aumentar.
Versiones de ECMAScript
A lo largo de los años, Javascript ha ido sufriendo modificaciones que los navegadores han ido implementando para acomodarse a la última versión de ECMAScript cuanto antes.
El presente de Javascript
A partir del año 2015, se marcó un antes y un después en el mundo de Javascript. Las últimas versiones de ECMAScript son las siguientes:
Ed. | Fecha | ECMAScript | Cambios significativos |
---|---|---|---|
16 | JUN/2025 | Set helpers, Iterator helpers, Promise.try, import attributes... | |
15 | JUN/2024 | groupBy, withResolvers, waitAsync, isWellFormed... | |
14 | JUN/2023 | findLast(), hashbang, toReversed(), toSorted()... | |
13 | JUN/2022 | at(), top-level await modules, private fields... | |
12 | JUN/2021 | Promise.any, globalThis, replaceAll(), flat(), flatMap()... | |
11 | JUN/2020 | Dynamic imports, BigInt, Promise.allSettled |
En ocasiones, algunos navegadores deciden implementar pequeñas funcionalidades de versiones posteriores de ECMAScript antes que otras, para ir testeando y probando características, por lo que no es raro que algunas características de futuras especificaciones puedan estar implementadas en algunos navegadores.
Una buena forma de conocer en que estado se encuentra un navegador concreto en su especificación de ECMAScript es consultando la tabla de compatibilidad Kangax. En dicha tabla, encontramos una columna «Desktop browsers» donde podemos ver el porcentaje de compatibilidad con las diferentes características de determinadas especificaciones de ECMAScript.
El pasado de Javascript
La siguiente lista de versiones las podemos considerar el pasado de Javascript:
Ed. | Fecha | Nombre formal / informal | Cambios significativos |
---|---|---|---|
10 | JUN/2019 | flat, flatMap, trimStart(), optional error catch... | |
9 | JUN/2018 | ECMAScript 2018 (ES9) | Rest/Spread operator, Promise.finally()... |
8 | JUN/2017 | ECMAScript 2017 (ES8) | Async/await |
7 | JUN/2016 | ECMAScript 2016 (ES7) | Array includes(), Exponenciación ** |
6 | JUN/2015 | ECMAScript 2015 (ES6) | Clases, módulos, hashmaps, sets, for of, proxies... |
5.1 | DIC/2011 | ECMAScript 2011 (ES5.1) | Cambios leves |
5 | DIC/2009 | ECMAScript 2009 (ES5) | Strict mode, JSON, etc... |
4 | AGO/2008 | ECMAScript 2008 (ES4) | Versión abandonada. |
3 | DIC/1999 | ECMAScript 1999 (ES3) | RegExp, try/catch, etc... |
2 | JUN/1998 | ECMAScript 1998 (ES2) | Cambios leves |
1 | JUN/1997 | ECMAScript 1997 (ES1) | Primera edición |
A partir de 2015, se toma como regla nombrar a las diferentes especificaciones por su año, en lugar de por su número de edición. Es por esto, que se recomienda hablar de ECMAScript 2015 en lugar de ECMAScript 6, por ejemplo.
Estrategia «crossbrowser»
Es muy habitual que el programador esté confuso en como empezar a programar y como escribir código para que sea compatible con los diferentes navegadores. ¿Cómo puede hacer el programador para garantizar que el código funcione en todos los navegadores?
Generalmente, toma una de las siguientes estrategias como filosofía a la hora de escribir su código:
1️⃣ Enfoque conservador: El programador decide crear código en una versión ECMAScript antigua. «Ignoras los problemas y escribes código viejo».
- 💖 El código será compatible en la mayoría de navegadores.
- 💖 No requiere configurar herramientas externas para transformar el código.
- 💔 Se deberá escribir mucho código para ciertas tareas.
- 💔 El código será antiguo y no podrá disfrutar de las últimas novedades de JS.
2️⃣ Enfoque delegador: El programador delega la responsabilidad de funcionar en navegadores a un framework o librería. «Te despreocupas y confías en que el framework lo hará bien».
- 💖 Más cómodo para el programador.
- 💖 El framework/librería gestiona esas tareas de forma transparente.
- 💔 El framework es una dependencia (si el framework muere, debemos cambiar a otro).
- 💔 Se suele perder algo de rendimiento y control (inapreciable en la mayoría de los casos).
3️⃣ Enfoque evergreen: El programador decide no preocuparse de la compatibilidad con navegadores antiguos, sino dar soporte sólo a las últimas versiones de los navegadores (evergreen browsers), o incluso sólo a ciertos navegadores. «Si no usas este navegador, no es mi problema».
- 💖 Cómodo para el programador.
- 💖 Ideal en casos donde puedes «obligar» al usuario a actualizar su navegador.
- 💔 Si tienes una gran masa de usuarios con navegadores antiguos, no les funcionará.
- 💔 Suele ser una fuente de problemas en muchos casos.
4️⃣ Enfoque transpilador: El programador crea código en la última versión de ECMAScript y utiliza una herramienta para transpilarla (herramienta para convertir el código a versiones antiguas de ECMAScript). «Quizás me cueste un poco más, pero puedo escribir código moderno y que funcione en todos lados.»
- 💖 Cómodo para el programador.
- 💖 Usas las últimas novedades de Javascript, y es compatible en navegadores antiguos.
- 💔 Es algo más complejo y en algunos casos debes realizar configuraciones.
- 💔 Debes asegurarte bien de no editar los ficheros transpilados, sino los originales.
Otros conceptos
Independientemente del enfoque que se decida utilizar, el programador también puede utilizar polyfills o fallbacks para asegurarse de que ciertas características funcionarán en navegadores antiguos. También puede utilizar enfoques mixtos.
Un polyfill no es más que una librería o código Javascript que actúa de «parche» o «relleno» para dotar de una característica que el navegador aún no posee, hasta que una actualización del navegador la implemente.
Un fallback es algo también muy similar: un fragmento de código que el programador prepara para que en el caso de que algo no entre en funcionamiento, se ofrezca una alternativa.