El operador ...spread.

facebook-svg gplus-svg twitter-svg

El operador spread permite expandir elementos iterables, como por ejemplo:
- arrays
- cadenas de texto
- objetos
- listas de nodos DOM ( NodeList )
- el objeto arguments de una función
- y otros dos tipos de estructuras nuevas en ES6: maps y sets.

Para entender de que va esto, veamos algunos ejemplos:

1. Arrays

Dado el siguiente array:

const ry = ["a","b","c","d","e"];

Si lo sacamos expandido en consola, conseguimos la lista de los elementos:

console.log(...ry);//  a b c d e f

Veamos algunos casos prácticos:

1.1. Copiar un array

Para copiar un array podemos utilizar el método slice() que devuelve una copia de una parte del array dentro de un nuevo array. Si utilizamos slice() sin argumentos conseguimos una copia del array original. El array original no se modificará.

var array2 = array1.slice();

También podemos copiar un array si concatenamos el primero array a un array vacio:

var array2 = [].concat(array1);

En ES6 podemos utilizar el operador spread con este propósito:


const array1 = ["A","B","C"]
const array2 = [...array1];
1.2. Combinar arrays

Parta combinar arrays podemos utilizar el método concat():

var array3 = array1.concat(array2);

En ES6 podemos utilizar el operador spread y los métodos push() o unshift()


const array1 = ["A","B","C"];
const array2 = [...array1];// la copia de array1
const array3 = ["D","E","F"];
array1.push(...array3);// array1 = ["A", "B", "C", "D", "E", "F"]
array2.unshift(...array3);// array2 = ["D", "E", "F", "A", "B", "C"]
1.3. Una alternativa para el método apply();

Cuando transformamos un color hsl en un color rgb el resultado tiene muchas veces el aspecto de un array. Por ejemplo para el rojo tenemos [255,0,0]. Asi que necesitamos una función que transforme este array en un color rgb verdadero:

function returnRGB(r,g,b){
    return `rgb(${r},${g},${b})`;
}

Pero esta función toma tres argumentos y nosotros tenemos un array:

const colorRy = [255,0,0];

La solución es utilizar el método apply de esta manera:

returnRGB.apply(null,colorRy);

Otra solución es utilizar el operador spread:


returnRGB(...colorRy);

También para encontrar el valor máximo o mínimo de un array necesitamos utilizar el método apply:

const numeros = [23,45,75,38,93,43];
const maximo = Math.max.apply(Math, numeros);
const minimo = Math.min.apply(Math, numeros);

Alternativamente podemos utilizar el operador spread:


const numeros = [23,45,75,38,93,43];
const maximo = Math.min(...numeros);
const maximo = Math.max(...numeros);

2. Cadenas de texto

Dada la siguiente cadena de texto

"Cadena de texto"

Si la sacamos en consola expandida dentro de un array

console.log([..."Cadena de texto"]);
//["C", "a", "d", "e", "n", "a", " ", "d", "e", " ", "t", "e", "x", "t", "o"]

Conseguimos el array de las letras de dicha cadena, muy útil si queremos dar un estilo aparte a cada letra ( por ejemplo ).

Un caso práctico

El siguiente ejemplo funciona en Chrome, Firefox y Opera.
Podemos dar estilo al texto que sacamos en la consola del navegador. Por ejemplo si queremos que el texto sea rojo podemos escribir:

console.log('%cERROR!!!', 'font-size=20px;color:red');

El especificador '%c' indica que habrá un segundo parámetro con los estilos CSS de  la cadena de texto que le sigue.

También podemos sacar varios mensajes en consola, cada uno con su estilo:

console.log('%cCadena1'+'%cCadena2', '/*CSS para Cadena1*/',  '/*CSS para Cadena2*/');

Lea más acerca de cómo sacar mensajes en consola: Diagnose and Log to Console

En el siguiente ejemplo sacamos un mensaje en la consola del navegador y queremos que cada letra tenga un color diferente. Para romper la cadena de texto y transformarla en un array utilizamos el operador spread.

[..."Colores en la consola del navegador";]

Ahora podemos utilizar el método map() para crear la variable strText, una cadena de texto que contiene el texto que queremos formatear.

[..."Colores en la consola del navegador"].map((el) =>{
  strText += ' %c'+el;
  strStyle.push('font-size:20px;color: hsl('+ ~~(Math.random()*360)+',100%,45%)');
});

y la variable strStyle, un array que contiene los estilos CSS para cada letra.

[..."Colores en la consola del navegador"].map((el) =>{
  strText += ' %c'+el;
  strStyle.push('font-size:20px;color: hsl('+ ~~(Math.random()*360)+',100%,45%)');
});

Finalmente sacamos el mensaje en consola:

console.log(strText,...strStyle);

Abra este ejemplo en Chrome, Firefox u Opera. No olvide abrir la consola de su navegador para ver el resultado.

See the Pen Colores en la consola del navegador & ES6 by Gabi (@enxaneta) on CodePen.

3. Listas de nodos DOM

Dado el siguiente HTML:


  <nav>
    <ul>
      <li>Index</li>
      <li>Nosotros</li>
      <li>Servicios</li>
      <li>Contáctanos</li>
    </ul>
  </nav>

Podemos conseguir la lista de los elementos <li>  utilizando el método querySelectorAll() o getElementsByTagName():

const menu = document.querySelectorAll("nav li");

La variable menu se parece mucho a un array, pero es de hecho una lista de nodos ( NodeList ). Esto quiere decir que aunque sea un elemento iterable, no lo podemos manipular utilizando métodos de los arrays como map ( por ejemplo )

Si lo sacamos en consola expandido

console.log(...menu);

Obtenemos la lista de los elementos <li> anidados dentro de <nav>.

Un caso práctico

Para recuperar el texto de los elementos <li> primero tenemos que expandir el menú en un array. Ahora podemos aplicar el método map() para recuperar el innerHTML de cada elemento:


console.log([...menu].map((el) => el.innerHTML));

4. El objeto arguments de una función

El objeto arguments  es una variable local disponible dentro de todas las funciones JavaScript. El objeto arguments contiene los argumentos de la función.

Veamos un ejemplo:

function veaLosArgumentos(){
    console.log(arguments)
  }

Si llamamos la función veaLosArgumentos("a","b","c","d","e"); obtenemos un objeto muy parecido a un array que contiene todos los argumentos pasados a la función.

Un caso práctico

Exactamente como en el caso de los elementos DOM, el objeto arguments es iterable, pero no lo podemos manipular utilizando métodos especificos de los arrays como map ( por ejemplo ). Para poder hacerlo necesitamos transformarlo en un array, y lo podemos hacer utilizando el operador spread:


function veaLosArgumentos2(){
    console.log([...arguments].map((el) => el.toUpperCase()))
}
veaLosArgumentos2("a","b","c","d","e"); // ["A", "B", "C", "D", "E", "F"]