El Shallow Copy (copia superficial) se refiere a la forma de crear un nuevo objeto a partir de las propiedades de otro. Esta copia solo se hace a un nivel alto, no se hace con objetos dentro de objetos (nested objects), lo que provoca que la modificación de una de sus propiedades, modifique el objeto principal.
Shallow copy con el bucle for
Podemos copiar las propiedades de un objeto en otro haciendo uso del bucle for:
const obj1 ={a:"a",b:"b"}const obj2 ={}for(propiedad in obj1){ obj2[propiedad]= obj1[propiedad];}
Si deseáramos modificar los valores de los atributos del objeto copia, el objeto original no se ve afectado:
Pero, si hay objetos dentro del objeto original (nested objects) el objeto original sí se vería afectado ante las modificaciones hechas en dichos sub objetos:
const obj1 ={a:"a",b:"b",c:{d:"d",e:"e"}}const obj2 ={}for(propiedad in obj1){ obj2[propiedad]= obj1[propiedad];}obj2.a="atributo a";obj2.b="atributo b";obj2.c.d="objeto dentro de otro";console.log(obj2);console.log(obj1);/* > Mensaje en consola
{
a: 'atributo a',
b: 'atributo b',
c: {
d: 'objeto dentro de otro',
e: 'e'
}
}
{
a: 'a',
b: 'b',
c: {
d: 'objeto dentro de otro',
e: 'e'
}
}
*/
Shallow copy con Object.assign
El Object.assign nos permite realizar el mismo shallow copy que podemos hacer con el bucle for.
const obj1 ={a:"a",b:"b",c:{d:"d",e:"e"}}const obj3 =Object.assign({}, obj1);// Con esto podemos crear copias exactasconsole.log(obj1);// { a: 'a', b: 'b', c: { d: 'd', e: 'e' } }console.log(obj3);// { a: 'a', b: 'b', c: { d: 'd', e: 'e' } }// Sin embargo, si hacemos modificaciones en los nested objects...obj1.c.d="COPIA DESDE EL OBJ1";// se verán afectados los demás objetos copiadosconsole.log(obj3);// { a: 'a', b: 'b', c: { d: 'COPIA DESDE EL OBJ1', e: 'e' } }
Aun así, tendremos los mismos problemas si el objeto original posee nested objects.
Object.create
Nos permite crear un objeto que tenga como parte de su prototipo los atributos de otro objeto:
Hasta ahora hemos podido resolver parcialmente el problema de copiar objetos, ya que aún tenemos inconvenientes cuando los objetos originales tienen anidados otros objetos. Tratemos de resolver esto con JSON.parse y JSON.stringify. 👨💻
Contribución creada por: Martín Álvarez (Platzi Contributor) con el aporte de Zajith Corro Viveros.
El Shallow Copy(copia superficial) es una copia bit a bit de un objeto. Se crea un nuevo objeto que tiene una copia exacta de los valores del objeto original. Si alguno de los campos del objeto son referencias a otros objetos, solo se copian las direcciones de referencia, es decir, solo se copia la dirección de memoria.
El método Object.assign () copia todas las propiedades propias enumerables de uno o más objetos de origen a un objeto de destino. Devuelve el objeto de destino modificado.
Las propiedades del objeto de destino se sobrescriben con las propiedades de los orígenes si tienen la misma clave. Las propiedades de las fuentes posteriores sobrescriben a las anteriores.
El método Object.create () crea un nuevo objeto, utilizando un objeto existente como prototipo del objeto recién creado.
La diferencia entre Object.create y Object.assign
La principal diferencia entre Object.create() y Object.assign() es que el método Object.assign crea un nuevo Object. utiliza el objeto proporcionado como prototipo del Objeto recién creado. Mientras que el método Object.assign() copia todas las propiedades de los objetos de origen al objeto de destino, que es el primer parámetro de esta función y devuelve este Objeto de destino.
Por lo tanto, vemos que mientras Object.create() define propiedades en nuestro Object recién creado. Object.assign() simplemente asigna el valor de los objetos de origen de destino a nuestro Objeto de destino.
Código Clase
const obj1 ={a:'a',b:'b',c:{d:'d',e:'e',},};// Shallow Copy con forconst obj2 ={};for(prop in obj1){ obj2[prop]= obj1[prop];}// Metodos de Object para hacer Shallow Copyconst obj3 =Object.assign({}, obj1);const obj4 =Object.create(obj1);
gracias por tu aporte me facilito la búsqueda individual
Muchas gracias por tu aporte, directo a mi Notion. Solo le cambié esta parte en el penúltimo párrafo:
"La principal diferencia entre Object.create() y Object.assign() es que el método Object.create() crea un nuevo Object."
Momento epico para los fans del anime en el min 5:32
Jajajajajaa, la rompiste amigo!
El for loop que se aplico es para aquellos tipos de datos que no son iterables, tales como los objetos literales, la sintaxis es bastante simple.
for(item in obj){ @code
}
Hay una sintaxis similar para aquellos tipos de datos que si son iterables, tales como strings o arrays:
for(item of arr){ @code
}
Genial explicación, útil para principiantes como yo. Gracias por el dato!
También podemos copiar las propiedades de un objeto usando el spread operator (...)
Ejemplo:
Ahora entiendo por que se dice que JavaScript es un lenguaje incomprendido :p
Estoy concluyendo muy temprano en eso.
🌧️ Shallow copy en JavaScript
Ideas/conceptos claves
Object.assign() copia todas las propiedades enumerables de uno o más objetos fuente a un objeto destino. Devuelve el objeto destino.
Object.create() crea un objeto nuevo, utilizando un objeto existente como el prototipo del nuevo objeto creado.
Recursos
Object.assign() - JavaScript | MDN
Object.create() - JavaScript | MDN
The Difference Between Object.create and Object.assign - CodeCalls
Apuntes
Para poder clonar un objeto en JavaScript “superficialmente” podemos realizarlo mediante diferentes formas
Recorriendo las propiedades del Objecto
const obj1 ={a:"a",b:"b",};const obj2 ={};for(prop in obj1){ obj2[prop]= obj1[prop]}
Lo que se realiza en el código anterior es iterar el objeto a copiar y pasar los valores en el nuevo objeto.
Lastimosamente, cuando se trata de objetos como atributos seguimos copiando solo la referencia, como por ejemplo:
const obj1 ={a:"a",b:"b",c:{d:"d"}};
Object.assign()
Object.assign() permite crear un nuevo objeto mediante la copia de otro
Recibe como parametro dos valores:
El objeto inicial donde se asignaran las propiedades del objeto a copiar
El objeto a copiar o asignar valores
const obj3 =Object.assign({}, obj1);
De igual forma los objetos como propiedades se siguen copiando las referencias
Object.create()
Object.create() crea un nuevo objeto, recibiendo un objeto anterior, pero todas las propiedades no estarán directamente en el objeto sino que en su prototipo
Recibe como parámetro el objeto a copiar
const obj4 =Object.create(obj1);
De igual forma sigue con el problema de que no puede copiar absolutamente un objeto
📌 **RESUMEN:** Shallow copy es copiar un objeto a nivel superficial sin tener en cuenta las otras referencias internas como propiedades que puede tener.
También podemos modificar las propiedades cuando las copiamos con Object.create() de la siguiente forma
obj4.__proto__.b="Esta es otra opcion"
Este método también modificaría el objeto madre que en este caso es obj1. Por que? porque estamos modificando el proto que en otras palabras es las características del objeto "original"
existen dos for para objetos,
for (objeto in objetos) {} >> IN es para iterar sus propiedades
for (objeto on objetos) {} >> ON es para iterar sus valores
A mi algo algo que me sirvió mucho fue recordar la clase de Freddy del curso gratis de programación básica en la que explica muy bien como accedes a los atributos de los objetos con los ciclos for utilizando index => (instancia in objeto) donde instancia itera en el índice y of => (instancia of objeto) y en of la instancia itera sobre el objeto
I si creamos un for donde verificamos que es un objeto para crear otro for y asignar así las propiedades!
Creo que el inicial con esa lógica seria un if else y luego si el for.
Por que? porque con el if verifica si es un objeto y con el for itera por el objeto para copiar los datos
Tambien en vez de copiar el objeto manualmente con un For lo podemos hacer usando las propiedades Object.keys y array.map
Confor:for(prop in obj1){ obj2[prop]= obj1[prop];}ConPropiedadesObject.keys(obj1).map(prop=>{ obj3[prop]= obj1[prop];})
Cuando me preguntan qué es JavaScript:
"Una cosa muy interesante que puede ser un error o un feature dependiendo de cómo quieras verlo"
Es como si obj4 heredara de obj1 pero los cambios que se le hagan a los objetos un nivel más interno afectaran tanto al original como a la copia, que cosas raras :|
Vaya lio el de copiar un Objeto
hola muy buenas
consulta no me quedo claro como se lee el for
Me cuentas si tienes alguna duda relacionada para ayudarte a resolverla. :muscle:
Holaa, un poco tarde, pero quizas ayude:
const obj ={a:"2",b:"3",c:{e:"e",d:"d"}}const obj2 ={}for(prop in obj){ obj2[prop]= obj[prop]console.log("soy obj[prop]")console.log(obj[prop])}/*Resultado:
soy obj[prop]
2
soy obj[prop]
3
soy obj[prop]
{e: 'e', d: 'd'}
Para entender este codigo, tenes que entender estas propiedades:
prop: de por si es: a,b,c dependiendo del momento del bucle en el que este. Es asi ya que dijimos que prop es parte de obj.
"obj2[prop] = ", esta propiedad hace 2 cosas a la vez.
1) Inicializa una variable en obj2, en este caso inicializaria asi: obj2[a], obj2[b], pero no solo eso, sino que al mismo tiempo:
2) Pero como a su vez hicimos "obj2[prop] = obj[prop]" Lo que estuvimos haciendo es asignar un elemento de obj[prop] en obj2[prop]
*/
que era prop
es el nombre de la variable la cual se usara en el ciclo, es decir, si pones en tu consola esto:
const obj1 = {
a:"a",
b:"b",
}
const obj2 = {}
for (cosa in obj1){
obj2[cosa] = obj1[cosa];
}
te deberia dar el mismo resultado, ya que cosa/prop sera la variable que recibira el dato durante el ciclo, espero haberme explicado bien :D
prop hace referencia a cada elemento del objeto. Sin embargo puedes colocar cualquier palabra, no es una palabra reservada. Por ejemplo si tienes un objeto:
let x ={a:1,b:2,c:3}
Para iterar puedes usar:
for(i in x){...}//que sería lo mismo quefor(prop in x)//i, prop o cualquier palabra que uses hace referencia a cada elemento del objeto o propiedad del objetofor(elemento in objeto){...}
y si usamos split operationpara haver una copia, alguien sabe que diferencia hay??
const elements =[1,2,3,4];//copy to new arrar whit split operationconst newArray =[...elements];
¡También nos ayuda a trabajar con inmutabilidad! :tada:
Te propongo un minireto:
¿Funciona con deep copy y nested elements?