Change Surfers

Más allá de JavasScript : Novedades ECMAScript 2019

Quizá no todos sepan que detrás de Javascript existe una organización (I) y una especificación formal (II) del lenguaje denominada ECMAScript que regula el progreso y la evolución del lenguaje, de forma que todas las implementaciones sean coherentes unas con otras (y cada motor Javascript usa la suya propia).

Este pasado Junio, el comité TC39 publicó una nueva versión del estándar ECMAScript (ECMA-262 10ª edición). Cómo el propio comité TC39 hace saber cada vez que tiene ocasión, esta nueva revisión no es más que un resumen (o puesta de largo) de las nuevas capacidades que el comité va aprobando e integrando dentro del lenguaje.

Object.fromEntries()

Se ha incluido un nuevo método fromEntries() que es el inverso del método entries() que existía previamente:

const obj = {
  name: 'John',
  age: '30'
};
const entries = Object.entries(obj)
// entries = [[“name", "John"],["age", "30"]]
Object.fromEntries(entries);
// { name: "John", age: "30" }

Este nuevo método sólo acepta objetos de tipo Array o Map.

Array.prototype.flat() && Array.prototype.flatMap()

El nuevo método flat() crea un nuevo array con todos los subarrays concatenados (admite como parámetro la profundidad):

let values = [1, [2, [3, 4], 5, 6]];
 values.flat();
// [1, 2, [3, 4], 5, 6]
 values.flat(2);
// [1, 2, 3, 4, 5, 6]

El método flatMap() combina un map() con un flat() (en ese orden):

let values = [1, 2, 3, 4, 5, 6];
values.map((value, index) => {
  return [value, value * index];
});
// [[1, 0], [2, 2], [3, 6], [4, 12], [5, 20], [6, 30]]
 values.flatMap((value, index) => {
  return [value, value * index];
});
// [1, 0, 2, 2, 3, 6, 4, 12, 5, 20, 6, 30]

String.prototype.trimStart() && String.prototype.trimEnd()

Se han añadido dos nuevos métodos (en realidad cuatro) para complementar la funcionalidad del método trim(). Recordemos que el método trim() se usaba para borrar caracteres en blanco al comienzo y al final de un string:

"    four empty characters both sides    ".trim()
// "four empty characters both sides"
"    four empty characters both sides    ".trimStart()
// "four empty characters both sides    "
// trimLeft es un alias de trimStart
"    four empty characters both sides    ".trimLeft()
// "four empty characters both sides    "
"    four empty characters both sides    ".trimEnd()
// "    four empty characters both sides"
// trimRight es un alias de trimEnd
"    four empty characters both sides    ".trimRight()
// "    four empty characters both sides"

A partir de aquí, explicamos unas modificaciones del standard que vienen a corregir ciertas deficiencias de la especificación que existían hasta ahora.

Catch binding opcional

Durante un try / catch el parámetro de error era necesario. A partir de ECMAScript 2019 dejará de serlo:

// Antes
try { // code } catch (error) { // catch }
// Ahora
try { // code } catch { // catch }

Function.prototype.toString()

Se modifica el comportamiento por defecto del método toString() de una función. Ahora devuelve comentarios y espacios en blanco:

function methodA() {
  // comentarios
  const a = '1';
  return a;
}
methodA.toString();
/*
"function methodA() {
  // comentarios
  const a = '1';
  return a;
}"

Symbol.prototype.description

El tipo Symbol recibe una nueva propiedad llamada description que puede leerse:

const newSymbol = Symbol('descripción del símbolo');
newSymbol.toString();
// "Symbol(descripción del símbolo)"
newSymbol.description
// "descripción del símbolo"

Array.prototype.sort()

A partir de esta revisión, todos lo navegadores que comiencen a implementar esta especificación deberán contar con un algoritmo de ordenado ‘estable’. Hasta ahora, el algoritmo que usaban los navegadores no tenía por qué respetar el orden previo de elementos. Muchos navegadores ya incluían este comportamiento, pero no era formaba parte del standard:

const movies = [
  { name: "Akira", nota: 9 },
  { name: "Blade Runner", nota: 9 },
  { name: "Capitán América: Soldado de Invierno", nota: 8 },
  { name: "Casablanca", nota:10 },
  { name: "Love Actually"nota: 8 },
  { name: "Pozos de ambición", nota: 10 },
  { name: "Star Wars: El Imperio Contraataca", nota: 10 }
];
movies.sort((a, b) => b.nota - a.nota);
/*{
  { name: "Casablanca", nota: 10 },
  { name: "Pozos de ambición", nota: 10 },
  { name: "Star Wars: El Imperio Contraataca", nota: 10} ,
  { name: "Akira", nota: 9 },
  { name: "Blade Runner", nota: 9 },
  { name: "Capitán América: Soldado de Invierno", nota: 8 },
  { name: "Love Actually", nota: 8 }
  }*/

En el ejemplo,l orden alfabético previo se respeta.

Cambios sobre el subconjunto JSON

Por un lado, el método stringify() ahora escapa correctamente ciertos caracteres que antes no era capaz de escapar:

// antes
JSON.stringify('\uD800'); // "'�'"
// ahora
JSON.stringify('\uD800'); // "'\\ud800'"

Por otro lado, ahora JSON es un subconjunto de ECMAScript, previamente no era así. La propuesta se puede leer en este enlace.

Las modificaciones para la revisión ECMAScript 2020 ya están en marcha y ya existen varias propuestas aceptadas (como la especificación para BigInt o la inclusión de un nuevo método a un array de promesas para gestionar cuando todas han terminado allSettled()).

Recordad que podéis consultar a partir de qué versiones de navegador están disponibles estos cambios en Can I use?.

Sergio del Valle Salvador – Senior Software Developer

Enlaces relacionados:
(I) Organización ECMAScript
(II) Especificación formal del lenguaje ECMAScript