ECMAScript 6 (ES6): novedades de la próxima versión de JavaScript
Probablemente ya hayas oído hablar de ECMAScript 6 (o ES6). Es la próxima versión de JavaScript y tiene algunas características nuevas excelentes. Las funciones tienen distintos grados de complejidad y son útiles tanto en scripts simples como en aplicaciones complejas.
En este artículo, analizaremos una selección cuidadosamente seleccionada de características de ES6 que puede utilizar en su codificación JavaScript diaria. Tenga en cuenta que la compatibilidad con estas nuevas funciones de ECMAScript 6 está en marcha en los navegadores modernos, aunque la compatibilidad varía. Si necesita admitir versiones antiguas de navegadores que carecen de muchas funciones de ES6, mencionaré soluciones que podrían ayudarlo a comenzar a usar ES6 hoy.
La mayoría de los ejemplos de código vienen con un enlace externo "Ejecutar este código", para que puedas ver el código y jugar con él.
variables
dejar
Estás acostumbrado a declarar variables usando var. Ahora lettambién puedes usarlo . La sutil diferencia radica en el alcance. Si bien varda como resultado una variable con la función circundante como alcance, el alcance de una variable declarada usando letes solo el bloque en el que se encuentra.
if(true) { let x = 1;}console.log(x); // undefined
Esto puede generar un código más limpio, lo que resulta en menos variables dando vueltas. Tome esta iteración de matriz clásica:
for(let i = 0, l = list.length; i l; i++) { // do something with list[i]}console.log(i); // undefined
A menudo se utilizaría, por ejemplo, la jvariable para otra iteración en el mismo ámbito. Pero con let, puedes ivolver a declarar con seguridad, ya que está definido y disponible solo dentro de su propio alcance de bloque.
constante
Hay otra forma de declarar variables con ámbito de bloque. Con const, declaras una referencia de solo lectura a un valor. Debes asignar una variable directamente. Si intenta cambiar la variable o si no establece un valor inmediatamente, obtendrá un error:
const MY_CONSTANT = 1;MY_CONSTANT = 2 // Errorconst SOME_CONST; // Error
Tenga en cuenta que aún puede cambiar las propiedades del objeto o los miembros de la matriz:
const MY_OBJECT = {some: 1};MY_OBJECT.some = 'body'; // Cool
Funciones de flecha
Las funciones de flecha son una gran adición al lenguaje JavaScript. Crean un código breve y conciso. Introducimos las funciones de flecha al principio de este artículo para poder aprovecharlas en otros ejemplos más adelante. El siguiente fragmento de código muestra una función de flecha, con la misma función escrita en el estilo familiar de ES5:
let books = [{title: 'X', price: 10}, {title: 'Y', price: 15}];let titles = books.map( item = item.title );// ES5 equivalent:var titles = books.map(function(item) { return item.title;});
- Ejecute este código
Si nos fijamos en la sintaxis de las funciones de flecha, no hay ninguna functionpalabra clave. Lo que queda es cero o más argumentos, la “flecha gruesa” (`=`) y la expresión de la función. La returndeclaración se agrega implícitamente.
Con cero o más de un argumento, debes proporcionar paréntesis:
// No argumentsbooks.map( () = 1 ); // [1, 1]// Multiple arguments[1,2].map( (n, index) = n * index ); // [0, 2]
Coloque la expresión de la función en un bloque ( { ... }) si necesita más lógica o más espacios en blanco:
let result = [1, 2, 3, 4, 5].map( n = { n = n % 3; return n;});
- Ejecute este código
Las funciones de flecha no sólo implican menos caracteres para escribir, sino que también se comportan de manera diferente a las funciones normales. Una expresión de función de flecha hereda thisy argumentsdel contexto circundante. Esto significa que puede deshacerse de declaraciones desagradables como var that = thisy no necesitará vincular funciones al contexto correcto. Aquí hay un ejemplo (nota this.titleversus that.titleen la versión ES5):
let book = { title: 'X', sellers: ['A', 'B'], printSellers() { this.sellers.forEach(seller = console.log(seller + ' sells ' + this.title)); }}// ES5 equivalent:var book = { title: 'X', sellers: ['A', 'B'], printSellers: function() { var that = this; this.sellers.forEach(function(seller) { console.log(seller + ' sells ' + that.title) }) }}
- Ejecute este código
Instrumentos de cuerda
Métodos
Se han agregado un par de métodos convenientes al Stringprototipo. La mayoría de ellos básicamente eliminan algunas soluciones con el indexOf()método para lograr lo mismo:
'my string'.startsWith('my'); //true'my string'.endsWith('my'); // false'my string'.includes('str'); // true
Sencillo pero eficaz. Se ha agregado otro método conveniente para crear una cadena repetida:
'my '.repeat(3); // 'my my my '
Literal de plantilla
Los literales de plantilla proporcionan una forma limpia de crear cadenas y realizar interpolación de cadenas. Quizás ya estés familiarizado con la sintaxis; se basa en el signo del dólar y las llaves ${..}. Los literales de plantilla están encerrados entre comillas invertidas. Aquí hay una demostración rápida:
let name = 'John', apples = 5, pears = 7, bananas = function() { return 3; }console.log(`This is ${name}.`);console.log(`He carries ${apples} apples, ${pears} pears, and ${bananas()} bananas.`);// ES5 equivalent:console.log('He carries ' + apples + ' apples, ' + pears + ' pears, and ' + bananas() +' bananas.');
- Ejecute este código
En la forma anterior, en comparación con ES5, son simplemente una conveniencia para la concatenación de cadenas. Sin embargo, los literales de plantilla también se pueden utilizar para cadenas de varias líneas. Tenga en cuenta que el espacio en blanco es parte de la cadena:
let x = `1...2...3 lines long!`; // Yay// ES5 equivalents:var x = "1...n" + "2...n" +"3 lines long!";var x = "1...n2...n3 lines long!";
- Ejecute este código
matrices
El Arrayobjeto ahora tiene algunos métodos de clase estáticos nuevos, así como nuevos métodos en el Arrayprototipo.
Primero, Array.fromcrea Arrayinstancias a partir de objetos iterables y similares a matrices. Ejemplos de objetos similares a matrices incluyen:
- el
argumentsdentro de una función; - un
nodeListdevuelto pordocument.getElementsByTagName(); - las nuevas estructuras
MapdeSetdatos.
let itemElements = document.querySelectorAll('.items');let items = Array.from(itemElements);items.forEach(function(element) { console.log(element.nodeType)});// A workaround often used in ES5:let items = Array.prototype.slice.call(itemElements);
- Ejecute este código
En el ejemplo anterior, puede ver que la itemsmatriz tiene el forEachmétodo que no está disponible en la itemElementscolección.
Una característica interesante Array.fromes el segundo argumento opcional mapFunction. Esto le permite crear una nueva matriz asignada en una sola invocación:
let navElements = document.querySelectorAll('nav li');let navTitles = Array.from(navElements, el = el.textContent);
- Ejecute este código
Luego tenemos Array.of, que se comporta de forma muy parecida al Arrayconstructor. Soluciona el caso especial al pasarle un argumento de un solo número. Esto resulta en Array.ofser preferible a new Array(). Sin embargo, en la mayoría de los casos, querrás utilizar matrices literales.
let x = new Array(3); // [undefined, undefined, undefined]let y = Array.of(8); // [8]let z = [1, 2, 3]; // Array literal
Por último, pero no menos importante, se han añadido un par de métodos al Arrayprototipo. Creo que los findmétodos serán bienvenidos para la mayoría de los desarrolladores de JavaScript.
finddevuelve el primer elemento para el cual regresa la devolución de llamadatrue.findIndexdevuelve el índice del primer elemento para el cual devuelve la devolución de llamadatrue.fill"sobrescribe" los elementos de una matriz con el argumento dado.
[5, 1, 10, 8].find(n = n === 10) // 10[5, 1, 10, 8].findIndex(n = n === 10) // 2[0, 0, 0].fill(7) // [7, 7, 7][0, 0, 0, 0, 0].fill(7, 1, 3) // [0, 7, 7, 7, 0]
Matemáticas
Se han agregado un par de métodos nuevos al Mathobjeto.
Math.signdevuelve el signo de un número como1,-1o0.Math.truncdevuelve el número pasado sin dígitos fraccionarios.Math.cbrtdevuelve la raíz cúbica de un número.
Math.sign(5); // 1Math.sign(-9); // -1Math.trunc(5.9); // 5Math.trunc(5.123); // 5Math.cbrt(64); // 4
Si desea obtener más información sobre las nuevas funciones numéricas y matemáticas de ES6 , el Dr. Axel Rauschmayer lo tiene cubierto.
Operador de propagación
El operador de extensión ( ...) es una sintaxis muy conveniente para expandir elementos de una matriz en lugares específicos, como argumentos en llamadas a funciones. Mostrarle algunos ejemplos es probablemente la mejor manera de demostrar lo útiles que son.
Primero, veamos cómo expandir elementos de una matriz dentro de otra matriz:
let values = [1, 2, 4];let some = [...values, 8]; // [1, 2, 4, 8]let more = [...values, 8, ...values]; // [1, 2, 4, 8, 1, 2, 4]// ES5 equivalent:let values = [1, 2, 4];// Iterate, push, sweat, repeat...// Iterate, push, sweat, repeat...
- Ejecute este código
La sintaxis extendida también es poderosa cuando se llaman funciones con argumentos:
let values = [1, 2, 4];doSomething(...values);function doSomething(x, y, z) { // x = 1, y = 2, z = 4}// ES5 equivalent:doSomething.apply(null, values);
- Ejecute este código
Como puede ver, esto nos salva de la fn.apply()solución alternativa que se utiliza con frecuencia. La sintaxis es muy flexible porque el operador de extensión se puede utilizar en cualquier parte de la lista de argumentos. Esto significa que la siguiente invocación produce el mismo resultado:
let values = [2, 4];doSomething(1, ...values);
- Ejecute este código
Hemos estado aplicando el operador de extensión a matrices y argumentos. De hecho, se puede aplicar a todos los objetos iterables, como NodeList:
let form = document.querySelector('#my-form'), inputs = form.querySelectorAll('input'), selects = form.querySelectorAll('select');let allTheThings = [form, ...inputs, ...selects];
- Ejecute este código
Ahora, allTheThingses una matriz plana que contiene el formnodo y sus inputnodos selectsecundarios.
Desestructurando
La desestructuración proporciona una forma conveniente de extraer datos de objetos o matrices. Para empezar, se puede dar un buen ejemplo utilizando una matriz:
let [x, y] = [1, 2]; // x = 1, y = 2// ES5 equivalent:var arr = [1, 2];var x = arr[0];var y = arr[1];
Con esta sintaxis, se puede asignar un valor a varias variables de una sola vez. Un buen efecto secundario es que puedes intercambiar fácilmente valores de variables:
let x = 1, y = 2;[x, y] = [y, x]; // x = 2, y = 1
- Ejecute este código
La desestructuración también funciona con objetos. Asegúrese de tener claves coincidentes:
let obj = {x: 1, y: 2};let {x, y} = obj; // x = 1, y = 2
- Ejecute este código
También puedes usar este mecanismo para cambiar los nombres de las variables:
let obj = {x: 1, y: 2};let {x: a, y: b} = obj; // a = 1, b = 2
Otro patrón interesante es simular múltiples valores de retorno:
function doSomething() { return [1, 2]}let [x, y] = doSomething(); // x = 1, y = 2
- Ejecute este código
La desestructuración se puede utilizar para asignar valores predeterminados a objetos de argumento. Con un objeto literal, puedes simular parámetros con nombre.
function doSomething({y = 1, z = 0}) { console.log(y, z);}doSomething({y: 2});
Parámetros
Valores predeterminados
En ES6, los medidores definen valores predeterminados para la función paraposible. La sintaxis es la siguiente:
function doSomething(x, y = 2) { return x * y;}doSomething(5); // 10doSomething(5, undefined); // 10doSomething(5, 3); // 15
- Ejecute este código
Se ve bastante limpio, ¿verdad? Estoy seguro de que has necesitado completar algunos argumentos en ES5 antes:
function doSomething(x, y) { y = y === undefined ? 2 : y; return x * y;}
Cualquier undefinedargumento o ningún argumento activa el valor predeterminado para ese argumento.
Parámetros de descanso
Hemos estado investigando al operador de propagación. Los parámetros de descanso son muy similares. También utiliza la ...sintaxis y le permite almacenar argumentos finales en una matriz:
function doSomething(x, ...remaining) { return x * remaining.length;}
Como puede ver, esto nos salva de la fn.apply()solución alternativa que se utiliza con frecuencia. La sintaxis es muy flexible porque el operador de extensión se puede utilizar en cualquier parte de la lista de argumentos. Esto significa que la siguiente invocación produce el mismo resultado:
sean valores = [2, 4]; hacer algo(1, ...valores);
- Ejecute este código
Hemos estado aplicando el operador de extensión a matrices y argumentos. De hecho, se puede aplicar a todos los objetos iterables, como NodeList:
let form = document.querySelector('#my-form'), inputs = form.querySelectorAll('input'), selects = form.querySelectorAll('select');let allTheThings = [form, ...inputs, ...selects];
- Ejecute este código
Ahora, allTheThingses una matriz plana que contiene el

Deja un comentario