El operador de propagación(spread operator), como su nombre lo dice, consiste en propagar los elementos de un iterable, ya sea un array o string utilizando tres puntos (...) dentro de un array.
// Para stringsconst array =[..."Hola"]// [ 'H', 'o', 'l', 'a' ]// En arraysconst otherArray =[...array]//[ 'H', 'o', 'l', 'a' ]
También se utiliza para objetos, pero esta característica fue añadida en versiones posteriores de ECMAScript y es denominada propiedades de propagación.
Cómo copiar arrays utilizando el operador de propagación
Para realizar una copia de un array, deberás tener cuidado de la referencia en memoria. Los arrays se guardan en una referencia en la memoria del computador, al crear una copia, este tendrá la misma referencia que el original. Debido a esto, si cambias algo en la copia, también lo harás en el original.
Cuidado con la copia en diferentes niveles de profundidad
El operador de propagación sirve para producir una copia en un solo nivel de profundidad, esto quiere decir que si existen objetos o arrays dentro del array a copiar. Entonces los sub-elementos en cada nivel, tendrán la misma referencia de memoria en la copia y en el original.
La manera de solucionar es más compleja, tendrías que emplear el operador de propagación para cada elemento en cada nivel de profundidad.
Sin embargo, recientemente salió una forma de producir una copia profunda con StructuredClone, aunque es una característica muy reciente, así que revisa que navegadores tienen soporte.
Este comportamiento también sucede para objetos dentro de otros objetos, u objetos dentro de arrays.
Parámetro rest
El parámetro rest consiste en agrupar el residuo de elementos mediante la sintaxis de tres puntos (...) seguido de una variable que contendrá los elementos en un array.
Esta característica sirve para crear funciones que acepten cualquier número de argumentos para agruparlos en un array.
El parámetro restsiempre deberá estar en la última posición de los parámetros de la función, caso contrario existirá un error de sintaxis.
// ❌ Malfunctionhola(primero,...rest, ultimo){...}// SyntaxError: Rest element must be last element.
Diferencias entre el parámetro rest y el operador de propagación
Aunque el parámetro rest y el operador de propagación utilicen la misma sintaxis, son diferentes.
El parámetro rest agrupa el residuo de elementos y siempre debe estar en la última posición, mientras que el operador de propagación expande los elementos de un iterable en un array y no importa en que lugar esté situado.
const array =[1,2,3,4,5]functionhola(primero, segundo,...resto){// <- Parámetro Restconsole.log(primero, segundo)// 1 2console.log(resto)// [3,4,5, "final"]}hola(...array,"final")//<- Operador de propagación//Lo mismo que hacer -> hola(1,2,3,4,5, "final")
Contribución creada por Andrés Guano (Platzi Contributor).
Te dejo unos ejemplos bastante peculiares con spread operators
Copia y pega esto en la consola de tu browser, te volará la cabeza.
let kissEmoji =[..."👩❤️💋👩"]console.log(kissEmoji)let familyEmoji =[..."👨👩👦👦"]console.log(familyEmoji)
Súper cool, no crees?
Tiene sentido si lo piensas al final ambos objetos son una composición de otros objetos
Está genial Irving! Gracias por compartir!
Yo pensaba que era un solo objeto.
Yo numerando los archivos para que coincidan con los de Oscar.
ajjajaja xd
Una diferencia importante de ambos parámetros, como dice la documentación, es que el spread syntax (...), lo que hace es desestructurar elementos de un objeto o array.
.
Sin embargo lo que hace la rest syntax (... pero usada como parámetro en una función), es "empaquetar" o "condensar" los valores enviados como un elemento, sea array u objeto.
.
Spread syntax: desestructura -> deconstruye
Rest syntax: empaqueta -> construye
Me ayudó esta explicación, gracias.
Chic@s dejo el codigo
Spread Operator
let person ={name:"Alexa",age:24};let country ="COL"let data ={...person, country };console.log(data);
Rest
functionsum(num,...values){console.log(values);console.log(num + values[0]);return num + values[0];}sum(1,1,2,3)
good
thanks
Soy la única que se emocionó con esto? jaja, siento que este operador me va a quitar dolores de cabeza.
Es de mis características favoritas de JS :D
Llegué demasiado tarde a este curso 😢. Hace poco estaba trabajando en un reto de otro curso y lo quise solucionar con un método de los arrays pero este modificaba el array original por lo cual necesitaba una copia del array original y duré un buen de horas buscando en Google cómo hacer la copia, hasta que pregunte en Stack Overflow y ahí me enseñaron este concepto.
Cómo copiar arrays utilizando el spread operator
Para realizar una copia de un array, deberás tener cuidado de la referencia en memoria. Los arrays se guardan en una referencia en la memoria del computador, al crear una copia, este tendrá la misma referencia que el original. Debido a esto, si cambias algo en la copia, también lo harás en el original.
Ojo, cuando manejen spread operator para objetos. Cuando existe el mismo parametro en dos objetos distintos y hacemos uso de esta funcion es posible perder propiedades del primer o segundo objeto entonces presten mucha atencion a en que parte del objeto estan haciendo la destructuracion.
Ejemplo:
const person1 ={name:'Oscar',age:32}const person2 ={name:'Emilano',job:'Developer',...person1
}console.log(person2)// Dara como output { name: 'Oscar', age: 32, job: 'Developer' }.// Esto gracias a que la destructuracion ocurre despues de la declaracion de// propiedades y esto reemplaza props con el mismo nombre.const person3 ={...person1,name:'Emiliano'}console.log(person3)// Dara como output { name: 'Emiliano', age: 32 } ya que la asignacion de la// propiedad "name" ocurre despues de que el spread op asignara la prop del// mismo nombre anteriormente
Recordemos que, a fin de cuentas, no todos los navegadores soportan las mismas caracteristicas de ECMAScript a pesar de existir como un estandar. Entonces muchas herramientas, como Babel, refactorizan las caracteristicas mas nuevas a sus implementaciones antiguas para homogeneizar la funcionalidad de js en todos los entornos.
Si quieren ver en vivo como se ve el codigo ECMAScript en js antiguo pueden acceder al siguiente sitio: https://babeljs.io
¡Excelente! Muchas gracias por esta aclaración.
Hola, Comunidad.
Les comparto mi aporte por si no entendieron la parte del
Rest Operator
Para yo poder entender un poco mejor el rest operator me tocó hacer este ejemplo:
functionsumarValores(numero,...valores){console.log(`Esto son los valores que estaré recibiendo como argumentos ${valores}`);// Esto son los valores que estoy recibiendo como argumentos 1,2,3,4,5,6,7,8,9,0console.log(`Esto es la suma de numero: ${numero} + el primer valor de valores: ${valores[0]} = `, numero + valores[0]);// Esto es la suma de numero: 20 + el primer valor de valores: 1 = 21// Este return nos permite finalizar la función y retornar los valoresreturn numero + valores[0];}sumarValores(20,1,2,3,4,5,6,7,8,9,0);// 21
Esto lo hice, ya que al principio no entendía muy bien el ejemplo de Oscar pero con su buena explicación pude realizar mi propio ejemplo y entender mejor.
Si creen que me olvidé de algo, estoy emocionado por saberlo.
Sé que esto debería ir como aporte pero para mí era una pregunta que la respondí mediante hacía el ejemplo.
¡Saludos!
Muchas gracias Juan! Me estaba pasando que no me quedaba del todo claro y con tu ejemplo me quedo super claro
Es importante que si deseas hacer uso del rest operator en los parámetros de una función, lo establezcas como el último en la lista de parámetros, si no te arrojara el siguiente error:
SyntaxError no detectado: el parámetro Rest debe ser el último parámetro formal
Resumen!
Spread operator | Operador de Propagación
El operador de Propagación, nos va a permitir trabajar con una lógica que podamos propagar a otros elementos sin necesidad de volverla a escribir.
Es un operador que ayuda a crear nuevas variables utilizando elementos de otras variables, y/o elementos nuevos.
let person ={name:'Julian',age:28}let country ='CO';let data ={...person, country};console.log(data);
PARAMETROS REST
traer elementos con rest parameter:
functionsum(num,...values){console.log(values);console.log(num + values[0]);return num + values [0];}sum(2,3,4,5);
Shout out para @Andrés Guano, que sin esos aportes dentro de los recursos, seguro después me sentiría medio perdido.
Spread Operator (Operador de Propagación)
El operador de propagación es una característica introducida en ECMAScript 6 (ES6) que te permite desplegar los elementos de un iterable (como un arreglo, objeto o cadena) en varios lugares. Se denota con tres puntos ....
El operador de propagación es bastante versátil y tiene varios usos en la programación en JavaScript. Aquí tienes algunas formas comunes de usar el operador de propagación:
Arreglos:
Puedes utilizar el operador de propagación para crear un nuevo arreglo al desplegar los elementos de un arreglo existente. Esto es útil cuando deseas clonar un arreglo o combinar varios arreglos en un solo arreglo.
const arreglo1 =[1,2,3];const arreglo2 =[...arreglo1];// Clona arreglo1const arregloCombinado =[...arreglo1,4,5];// Combina arreglo1 y elementos adicionales
Argumentos de Función:
El operador de propagación se puede usar para pasar elementos de un arreglo como argumentos a una función.
functionsumar(a, b, c){return a + b + c;}const numeros =[1,2,3];const suma =sumar(...numeros);// Equivalente a sumar(1, 2, 3)
Propiedades de Objetos:
En ES6, el operador de propagación también se puede usar para crear un nuevo objeto al desplegar las propiedades de un objeto existente.
const obj1 ={x:1,y:2};const obj2 ={...obj1,z:3};// Crea un nuevo objeto con propiedades de obj1 y z
Combinar Arreglos:
Puedes combinar arreglos utilizando el operador de propagación en lugar de utilizar métodos como concat.
Listas de Argumentos de Función:
El operador de propagación se puede usar para convertir un objeto similar a un arreglo (como el objeto arguments) en un arreglo real.
Recuerda que el operador de propagación crea copias superficiales de los elementos que despliega. Esto significa que si estás desplegando un arreglo u objeto que contiene arreglos u objetos anidados, los elementos anidados aún harán referencia a los mismos objetos en memoria.
Si necesitas una copia profunda, deberás utilizar otras técnicas como la recursión o bibliotecas que manejen la clonación profunda.
En resumen, el operador de propagación es una forma poderosa y concisa de trabajar con arreglos, objetos y otros iterables en JavaScript.
Espero les sirva. 👨💻
Gente, recuerden que si bien el spread operator sirve para copiar propiedades de un objeto y elementos de un array simple, no funciona tan bien si hay objetos anidados o métodos en dicho objeto o array, allí ya se necesitaría hacer una deep copy como se ve en el curso intermedio de POO.
Tener en cuenta a la hora de usar spread
let obj = { id: 1, nombre: “Fulano” };
NO es lo mismo:
obj = { id: 2, …obj}; // Esto devuelve { id: 1, nombre: “Fulano” }
Las keys que escribas antes del spread, seran reemplazadas con el spread si ya existen, por lo cual si se desea modificar un valor, el spread debe ir antes de colocar dicho valor
¿Por qué el aporte de la clase no coincide con lo que el maestro enseña?
El profe solo menciona unas cosas y el aporte trae como 4 cosas extras o a veces vitales
si, es cierto, en vez de ayudar a aclarar solo confunde
Si pues, es lamentable porque otros estudiantes becarios ya vieron los cursos mientras salen otros y meten código raro que confunde a los que están siguiendo la ruta siguiendo un orden de básico a avanzado. Pero en parte podría ayudar a futuro para poder ver cuanto hemos avanzado.
al no colocar [0] en values por qué me sale como resultado 15,5
Hola Johel, según veo ese 15,5 que retorna la función no es un valor numérico sino un string. Eso pasa porque JavaScript utiliza el operador de suma como concatenación, al no poder convertir el array en un valor numérico. Por eso es que aparece 15,5 porque concatena el 1, el 5, la coma (,) y el último 5.
pero si no le pongo los 3 puntos que pasa
Hola Edgar, lo pasa es lo siguiente:
let data = { person, country };
vas a obtener esto: { person: { name: 'Oscar', age: 28 }, country: 'MX' }
No se integra el elemento country dentro del objeto
let data = { ... person, country };
vas a obtener: { name: 'Oscar', age: 28, country: 'MX' }
Es decir que se va a integrar el elemento country dentro del objeto person.
Cuidado con el ejercicio de desestructuración...
En los recursos de la clase hay un ejercicio de desestructuración con un error, se utiliza const en lugar de let y esto hace que el resultado no funcione como debería ser.
Pregunta en el Rest: ¿Porque se utilizaconsole.logy luegoreturncual es la necesidad de utilizar ambos?// rest