Skip to content
Aprende Angular de forma rápida y efectiva  Ver curso

Javascript ES2019: Todas las novedades

Javascript es un lenguaje en constante movimiento, con renovaciones anuales desde 2015. Hoy te traigo un resumen de ES2019, la actualización del estándar en 2019.

Principales novedades

Array.prototype.flat()

Éste método que se añade a la clase array con ES2019, permite aplanar un array multidimensional. Hasta el momento, para aplanar arrays tenías que hacerlo a mano o tirar de librerías externas como lodash.

Mira como funciona:

const arr = ['1', '2', ['3.1', '3.2'], '4', ['5.1', ['5.2.1', '5.2.2']], '6'];

arr.flat();       // ["1", "2", "3.1", "3.2", "4", "5.1", Array(2), "6"]
arr.flat(2);      // ["1", "2", "3.1", "3.2", "4", "5.1", "5.2.1", "5.2.2", "6"]
arr.flat().flat();// ["1", "2", "3.1", "3.2", "4", "5.1", "5.2.1", "5.2.2", "6"]

Como puedes ver, por defecto Array.flat() aplana el array un solo nivel. Si tienes arrays con más niveles de profundidad, puedes encadenar llamadas a flat(), o bien pasarle un parámetro con la profundidad necesaria.

Array.prototype.flatMap()

El método flatMap(callback) de ES2019 combina el método map(callback) con el flat() anterior, para transformar y aplanar un array de forma eficiente.

const arr = [[1, 20], [3, 40], [5, 60]];

arr
 .map(([a, b]) => [a, b / 10]) // [[1, 2], [3, 4], [5, 6]]
 .flat() // [1, 2, 3, 4, 5, 6]

arr.flatMap(([a, b]) => [a, b / 10]) // [1, 2, 3, 4, 5, 6]

Como puedes ver, a nivel funcional flatMap es equivalente a llamar primero el método map y acto seguido, encadenar el método flat a profundidad 1.

Object.fromEntries()

Object.fromEntries() transforma una lista de pares [clave-valor] en un objeto de claves, con los valores asociados.

const cartArray = [['apples', 3], ['bananas', 2], ['plums', 6]];
const cartObject = Object.fromEntries(cartArray);
// cartObject is {apples: 3, bananas: 2, plums: 6}

Object.fromEntries() es por tanto el proceso contrario al método entries() que se añadió a la clase Object en 2017.

Otras novedades

Catch binding opcional

Este cambio de ES2019 permite omitir el binding de un parámetro en el bloque catch de un try/catch. Es decir:

// before ES2019
try {
    throw new Error('something is wrong');
} catch(e) {
    console.log('why do I need "e" if I do not use it?');
}

// after ES2019
try {
    throw new Error('something is wrong');
} catch {
    console.log('catched, go ahead');
}

Hasta este cambio, era necesario añadir ese parámetro para recibir el error, aunque luego no fueras a hacer nada con él.

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

El método trimStart() elimina los espacios en blanco al principio de un string, mientras que trimEnd() elimina los del final.

const spacedHello = "    hello    ";
spacedHello.trimStart(); // "hello    "
spacedHello.trimEnd(); // "    hello"

Muchos navegadores soportaban ya estos mecanismos con diferente nomenclatura (trimLeft y trimRight), aunque no estaba estandarizado.

En ES2019, se incorporan al estándar como trimStart y trimEnd por consistencia con su proceso contrario, añadido en 2017 (padStart/padEnd).

Además, trimLeft y trimRight se añaden también como alias de trimStart y trimEnd, para mantener la compatibilidad con los navegadores.

Cambios en Function.prototype.toString()

El método toString() de una función devuelve un string con el código fuente de dicha función. Hasta 2019, esta función eliminaba espacios en blanco, comentarios y saltos de línea. Ahora ya no.

const sum = (...params) => {
    //params is an array containing all parameters received
    return params.reduce(
        (total, current) => total + current,
        0 // initial value
    )
};


sum.toString();
// "(...params) => {
//     //params is an array containing all parameters received
// 
//     return params.reduce(
//         (total, current) => total + current,
//         0 // initial value
//     )
// }"

Symbol.prototype.description

Ahora puedes obtener la descripción de un Symbol a través de su nueva propiedad description, en lugar de tener que usar el método toString().

const mySymbol = Symbol('MySymbol')
mySymbol.description // 'MySymbol'

Mejoras en JSON.stringify

Se ha mejorado la función stringify() para evitar malformaciones con determinadas cadenas Unicode.

Antes de ES2019, llamar a JSON.stringify() con símbolos UTF-8 entre \uD800 y \uDFFF, devolvía un carácter Unicode mal formado (un “�”). Ahora esos símbolos se pueden representar de forma segura como string usando JSON.stringify().

Puedes profundizar en los detalles aquí.

JSON superset

Se ha extendido la sintaxis de ECMAScript (la que usa JS) para ser un superset de JSON.

Antes de este cambio, los símbolos de separador de línea (\u2028) y separador de párrafo (\u2029) no estaban permitidos en strings parseados a JSON. Usando JSON.parse(), esos caracteres lanzaban un SyntaxError pero ahora se parsean correctamente, tal y como define el estándar JSON.

Reflexiones personales

JS sigue evolucionando, aunque sea a un ritmo tranquilo. Las novedades de ES2019 no son revolucionarias, pero algunas de ellas afectan al día a día de un desarrollador JS…

  • ¿Cuantas veces has tenido que aplanar arrays y has importado la librería lodash para conseguirlo?
  • ¿Cuantas veces has tirado de reduce para convertir un array de pares clave-valor en un objecto, a costa de sacrificar la facilidad de lectura del código?

Con esta revisión, JS no se centra en grandes cambios, si no en solucionar pequeños problemas que nos encontramos en nuestro día a día y eso, amigo, es de agradecer.

¿Te ha gustado este artículo? No te cortes, déjame un comentario y ayúdame a compartirlo 😉

Published inES6Javascript

4 Comments

  1. Simón Simón

    Excelente resumen. Muchas gracias Enrique!

  2. Pablo Coronel Pablo Coronel

    Muy útil el post, muchas gracias Enrique!!!

  3. Lady Sun Catheart Lady Sun Catheart

    La cuestión aquí es la obsesión de sacar cada año algo nuevo: todos los años una nueva versión de Android, una nueva versión del framework de turno… todos lo años una nueva versión de EcmaScript! deberiamos centrarnos en sacar versiones sin importar el tiempo que tome (obviamente no nos pasemos y no dejemos a una comunidad colgada más de 5 años). Me encanatría que mejorase el azucar sintáctico para los objetos, todavía no esta incluido variables privadas en JS y creo que ha sido en la época de prototipado uno de los mayores quebraderos de cabeza que hemos tenido. Estamos viendo en estandar web que estan a la delantera frameworks antes que las propias bases en que se sustentan. Supongo que en parte la culpa ha sido el lastre de las compatibilidades entre navegadores.

  4. Jordi Jordi

    La cantidad de versiones y actualizaciones de sofware genera un cierto sobreesfuerzo para estar al día. Para optimizar el tiempo se debería poder distinguir mas fácilmente la parte de mejora interna del sofware (necesaria y encomiable) de la parte que es un cambio realmente significativo para el usuario de esas herramientas. Excelente blog. Felicidades Enrique!!

Deja un comentario