Javascript se mueve. El mundo del desarrollo web tiene un ritmo bastante rápido. Y si hablamos de frontend, la cosa se pone mucho más frenética: antes de sacar a producción un proyecto, es bastante habitual que el framework o las herramientas con las que has construido ese proyecto se hayan quedado atrás. En nuestro mundo la constante es el cambio…Pero nos hemos acostumbrado y encima, nos gusta.
Pero más allá de gulps, webpacks, react o angular, el cambio más importante en el universo Javascript, llegó en Junio de 2015: El comité técnico 39 de ECMA (o TC-39), compuesto por representantes de los principales navegadores, publicó la especificación ES6, que pasaría a denominarse ECMAScript 2015. Suponía el cambio más grande en la especificación del lenguaje.
La adopción de la nueva especificación está siendo un proceso paulatino. Tanto los principales navegadores, como es el caso de Node.js, van añadiendo nuevas funcionalidades en cada versión que se va publicando. En esta tabla, se puede consultar el grado de adopción según cada plataforma javacriptiana del mercado.
No obstante, tenemos a nuestra disposición los denominados transpiladores, entre los que destaca BabelJS. El objetivo de este software consiste en “traducir” nuestro código ECMAScript2015 a ES5 de toda la vida. Gracias a esto podemos escribir según las nuevas especificaciones del lenguaje, sin esperar a que estén soportadas en las plataformas donde van a ejecutarse. En definitiva: No hay excusa.
El objetivo de este post es intentar motivar a aprender este nuevo estándar mediante una pequeña muestra de trucos para hacer cosas que antes, en ES5, eran tediosas y daban bastante pereza.
Gracias a las particularidades del lenguaje, programar Javascript no sólo es más fácil, sino que evita multitud de las trampas a las que Javascript nos tenía acostumbrados.
Y si un código es más fácil, es más entendible. Y si es más entendible, es más mantenible. Y si es más mantenible, tiene menos bugs: conseguimos un producto mejor y más barato.
Magia potagia
Desestructurando argumentos
Se pueden recibir los argumentos de una función directamente mediante una expresión de desestructuración, de manera que cada uno de ellos esté disponible en una función:
function talk({quien, que} = {}) {
console.log(quien + ‘ dice ‘ + que);
}
talk({quien: ‘yo’, que: ‘hola!’});
// yo dice hola!
Tirando un poco más del hilo, podemos añadir valores por defecto en esa expresión de desestructuración:
function talk({quien = ‘nadie’, que = ‘nada’} = {}) {
console.log(quien + ‘ dice ‘ + que);
}
talk({quien: ‘yo’});
// yo dice nada
talk();
// nadie dice nada
Extender un objeto
Esta funcionalidad está presente en todos los manuales de ECMAScript 2015. Hace uso del operador de propagación (…), para extender objetos; aunque también puede aplicarse a arrays y Maps.
function talk(args) {
let parameters = {
quien: 'nadie',
que: 'nada',
...args
};
console.log(parameters.quien + ‘ dice ‘ + parameters.que);
}
talk({quien: ‘yo’});
// yo dice nada
talk();
// nadie dice nada
Parámetro obligatorio
Dada su enorme versatilidad, con Javascript no es necesario especificar los parámetros que le llegan a una función. Y con ECMAScript 2015 esto se hace más sencillo gracias a los argumentos por defecto: el operador de propagación (…) en combinación con la desestructuración como acabamos de ver.
El problema viene a la inversa: ¿Qué hacer si nuestra función necesita que un argumento sea obligatorio? Existen varias opciones, pero todas pasan por hacer comprobaciones manuales.
Gracias a la funcionalidad de valor por defecto especificada en ECMAScript2015, podemos hacer esta comprobación algo más sencilla:
function required() {
throw Error(‘Error: required parameter not found!’);
}
function cuadrado(numero = required()) {
return numero*numero;
}
console.log( cuadrado(2));
// 4
console.log(cuadrado());
// ‘Error: required parameter not found!’
Fuente: 1ality
Push condicional a un array
Este siguiente truco, quizás se pueda considerar un poco “oneliner” (para mal)… Digamos que aunque se pueda hacer, a veces no es aconsejable evitar un if, ya que el resultado hace que nuestro código sea poco legible.
Aún así, el ejemplo sirve para mostrar un poco más el poder del operador de propagación (spread), esta vez con arrays:
let frutas = ['pera','manzana'];
let verduras = ['acelgas'];
let cereales = null;
let carrito = [
...(frutas? frutas:[]),
...(verduras? verduras:[]),
...(cereales? cereales:[])
];
console.log(carrito); // [ 'pera', 'manzana', 'acelgas' ]
Fuente: https://medium.com/@se.mo.moosavi/my-es6-tricks-beb58004c15d
Eliminar duplicados de un array
Gracias a la estructura de datos Set, instanciable con un iterador, y que no permite valores duplicados, tenemos una rápida forma de eliminar duplicados de un array. Al parecer no parece tener un gran rendimiento con arrays grandes, pero puede ser útil en determinadas circunstancias:
let myData = [1,2,5,3,5,1];
console.log([...new Set(myData)]; // [1,2,5,3]
Fuente: https://twitter.com/DaniStefanovic/status/828499976745545728
Clases Abstractas
El modelo de clases presentado en ECMAScript2015, quizás sea de las funcionalidades más revolucionarias. Pasamos del modelo basado en prototype, a un modelo de clases más natural para la mayoría de programadores.
Aún así, el concepto de clase abstracta no está soportado de serie, pero puede ser implementado de una forma relativamente indolora:
class Animal {
constructor() {
if (this.constructor === Animal) {
throw new TypeError('Abstract class "Animal" cannot be instantiated directly.');
}
}
walk() {
console.log(`Soy un ${this.name} andando`);
}
}
class Perro extends Animal {
constructor() {
super();
this.name = ‘perro’;
}
}
let toby = new Perro();
toby.walk(); // Soy un perro andando
let enjendro = new Animal(); //TypeError: Abstract class "Animal" cannot be instantiated directly.
Fuente: https://ilikekillnerds.com/2015/06/abstract-classes-in-javascript/
Futuro
Ha habido que esperar demasiado (desde la publicación de ES5 en Diciembre de 2009) hasta que hemos tenido disponible la nueva especificación del lenguaje.
Es por eso que lo que iba a llamarse ES6, se cambió de nombre y pasó a llamarse ECMAScript2015. La idea es poder sacar especificaciones años tras año, sin imponerse metas más ambiciosas que puedan retrasar una gran revisión; tal y como ha ocurrido con ES6.
Así pues, en 2016, hemos asistido a la aparición de un par de funcionalidades nuevas (Array.prototype.includes y el operador de exponenciación), mientras que en la especificación de 2017 veremos, entre otras, las tan esperadas funciones async/await. Mientras tanto, navegadores, engines y transpiladores van adoptando e implementando estas funcionalidades paulatinamente.
Por su parte, Microsoft ha publicado Typescript, un superconjunto construido encima de Javascript, cuya principal característica es que añade tipado fuerte al lenguaje. Es un lenguaje de código abierto que compila a Javascript. Este es el lenguaje escogido por la gente de Angular, sobre el que han construido la versión 2 del framework.
Se desconoce si ECMAScript adoptará tipado fuerte u otras funcionalidades de TypeScript. Es algo que dependerá y se decidirá en base a la propuesta desde el TC-39. Lo que está claro es que esto se mueve, y va a ir cada vez más rápido.
Queremos tu opinión :)