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 😉
Excelente resumen. Muchas gracias Enrique!
Muy útil el post, muchas gracias Enrique!!!
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.
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!!