Introducción
El operador de propagación es una característica de JavaScript introducida con ES6 que le da acceso al interior de un objeto iterable . Un “objeto iterable” es cualquier cosa sobre la que pueda iterar elemento por elemento, como matrices, objetos literales y cadenas. Estos tipos de JavaScript se pueden recorrer de alguna manera secuencial. Por ejemplo, puede usar un forbucle en una matriz o, con objetos JavaScript, puede usar for...inbucles .
Los conceptos básicos del operador Spread
El operador de propagación le otorga acceso a todos los elementos dentro de estos objetos iterables. Veamos un ejemplo para ilustrar lo que esto significa:
const foo = [ 'hello', 'bonjour', 'konnichiwa'];const bar = [...foo]; // the three dots "..." are the spread operator syntax.console.log(bar);
Ejecutar esto en la consola debería imprimir lo siguiente:
Producción
['hello', 'bonjour', 'konnichiwa'];
La variable barterminó siendo una copia exacta de la variable foo. El operador de propagación básicamente “vació” el interior de la foomatriz y distribuyó los valores en la nueva matriz en bar.
Es importante tener en cuenta los corchetes que rodean el operador de propagación, [...foo]. El operador de propagación distribuye estos valores dentro de un nuevo objeto del mismo tipo; en este caso, un literal de matriz. Intente ejecutar el código sin los corchetes:
const foo = [ 'hello', 'bonjour', 'konnichiwa'];const bar = ...foo;console.log(bar);
Producción
Uncaught SyntaxError: expected expression, got '...'
Ahora que tenemos una idea básica, veamos tareas comunes en las que el operador de propagación podría ser útil.
Duplicación de objetos iterables
Como vimos antes, el operador de propagación es una de las mejores formas de duplicar un objeto iterable. Hay formas más complejas de hacerlo, pero la concisión del operador de propagación lo hace deliciosamente fácil. El uso del operador de propagación para duplicar literales de objetos no es muy diferente que para matrices. Por ejemplo:
const foo = { english: 'hello', french: 'bonjour', japanese: 'konnichiwa'};const bar = {...foo};console.log(bar);
Esto nos lleva a lo siguiente:
Producción
{ english: 'hello', french: 'bonjour', japanese: 'konnichiwa' }
Fusión de objetos iterables
El operador de propagación también se puede utilizar para componer un único objeto iterable a partir de varios otros.
const foo = ['hello', 'bonjour', 'konnichiwa'];const bar = ['gutentag', 'saluton'];const baz = [...foo, ...bar];console.log(baz);
Esto mostrará el contenido de fooy barque ahora está contenido en baz:
Producción
['hello', 'bonjour', 'konnichiwa', 'gutentag', 'saluton']
También puedes colocar una matriz dispersa dentro de otra matriz como lo harías con cualquier otro elemento:
const foo = ['hello', 'bonjour', 'konnichiwa'];const bar = [...foo, 'gutentag', 'saluton'];console.log(bar);
Ahora barcontiene algunas adiciones a foo:
Producción
['hello', 'bonjour', 'konnichiwa', 'gutentag', 'hello-ey']
Una buena forma de pensarlo es que el operador de propagación solo contiene los elementos dentro del objeto iterable, en lugar de los objetos en sí.
¿Qué sucede con los literales de objeto? Es muy similar a fusionar matrices:
const foo = { english: 'hello', french: 'bonjour', japanese: 'konnichiwa'};const bar = { german: 'gutentag', esperanto: 'saluton'};const baz = {...foo, ...bar};console.log(baz);
Como el operador de propagación para los dos objetos contiene los elementos internos de esos objetos, usarlos en el contexto de un nuevo literal de objeto garantizará que también tengan esos contenidos.
Producción
{ english: 'hello', french: 'bonjour', japanese: 'konnichiwa', german: 'gutentag', esperanto: 'saluton' }
Esta es una tarea común, Object.assign()pero la sintaxis extendida la hace mucho más concisa.
Nota: Si bien puede combinar objetos iterables de diferentes tipos utilizando el operador de propagación, esto puede generar algunos comportamientos no deseados. En el caso de matrices y cadenas, puede pensar en ellas como objetos donde las claves son el índice del elemento o la letra en la matriz (por ejemplo: {0: 'a', 1: 'b', 2: 'c'}. Si utiliza el operador de propagación para una matriz o cadena en el contexto de un literal de objeto, sus resultados contendrán estos pares clave/valor. Sin embargo, dado que los objetos tienen claves que no son números, no podrá utilizar sus valores en un contexto de matriz.
¿Qué pasa cuando hay claves duplicadas?
const foo = { english: 'hello', french: 'bonjour', japanese: 'konnichiwa'};const bar = { english: 'howdy', german: 'gutentag'};const baz = { ...foo, ...bar, esperanto: 'saluton', korean: 'annyeong'};console.log(baz);
Aquí, fusionamos dos objetos existentes en un tercero, ambos contienen una entrada para english.
Producción
{ english: 'howdy', french: 'bonjour', japanese: 'konnichiwa', german: 'gutentag', esperanto: 'saluton', korean: 'annyeong' }
Las claves duplicadas se sobrescriben en el orden en que se aplican. Es importante tener en cuenta si se perderán o no datos valiosos en el proceso de uso del operador de propagación para fusionar objetos iterables.
Introducir argumentos en las funciones
El operador de propagación se puede utilizar en muchos casos en los que se podría optar por utilizar el applymétodo que pasa los valores de una variable a una función de manera similar.
function calcVolume(width, height, depth) { return width * height * depth;};calcVolume(12, 30, 14); // basic// Passing arguments to the function from a variable:const cube = [12, 30, 14];calcVolume.apply(null, cube); // using "apply"calcVolume(...cube); // using "spread operator"
El operador de propagación facilita la introducción de una serie de argumentos en funciones en casos en los que applypueden no ser totalmente aplicables.
Uso del operador de propagación con cadenas
Por último, también puedes utilizar el operador de propagación con cadenas, ya que también se consideran un objeto iterable.
const foo = "jumanji";const bar = [...foo];console.log(bar);
Esto dividirá la cadena jumanjien sus caracteres individuales.
Producción
// [ "j", "u", "m", "a", "n", "j", "i" ]
Conclusión
El operador de propagación era una característica muy solicitada en otros lenguajes como C++ y Python, ¡y ahora está aquí en ES6! Facilita mucho la realización de algunas tareas de programación comunes y, con este tutorial, aprendiste formas prácticas de usarlo. Para obtener más información sobre el operador de propagación, MDN tiene documentación detallada disponible.