Como vimos en otro post, Paso por Valor Paso por Referencia, los elementos que no son tipos primitivos, al igualarlos a otros, se pasa la referencia.
var persona1 = {nombre:"Ruben",edad:25}; var persona2 = {nombre:"Ale",edad:20}; console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1 = persona2; console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1.nombre = "Pepe"; console.log("Persona1:",persona1,"\nPersona2:",persona2);
¿Entonces como hacemos para copiar solamente el valor de un Objecto a otro en Javascript?
Método 1:
var persona1 = {nombre:"Ruben",edad:25}; var persona2 = {nombre:"Ale",edad:20}; console.log("Persona1:",persona1,"\nPersona2:",persona2); //persona1 = Object.assign({}, persona2); //Copia tal cual el objeto persona1 = Object.assign({}, persona2, { nombre:"Juan", edad: 40, pelo:"castaño" }); //Copio el objeto y le pongo propiedades personalizadas console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1.nombre = "Pepe"; console.log("Persona1:",persona1,"\nPersona2:",persona2);
Método 2:
var persona1 = {nombre:"Ruben",edad:25}; var persona2 = {nombre:"Ale",edad:20}; console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1 = {...persona2}; console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1.nombre = "Pepe"; console.log("Persona1:",persona1,"\nPersona2:",persona2);
***Solo para el nivel 1 de copia profunda.
Objetos mas complejos (Objetos dentro de Objetos):
var redessociales = {facebook:{ cuentapersonal:"ruben@facebook.com", cuentaprofesional:"rubenpro@facebook.com"}, instagram:"@ruben"} var persona1 = {nombre:"Ruben",edad:25}; var persona2 = {nombre:"Ale", edad:20, social:redessociales, getEdad:function(){ return this.edad;} }; console.log("Persona1:",persona1,"\nPersona2:",persona2); //persona1 = {...persona2}; //Cualquiera de los dos casos persona1 = Object.assign({},persona2); console.log("Persona1:",persona1,"\nPersona2:",persona2); persona2.social.facebook.cuentapersonal = "NUEVACUENTA"; console.log("Persona1:",persona1,"\nPersona2:",persona2);
¿Que ha pasado con el objeto redes sociales dentro del objeto Persona1?
¿Un objeto dentro de otro objeto?
Ha cambiado al cambiar Persona2 … Nos ha copiado la referencia!! No nos vale!
Método 3:
var redessociales = {facebook:{ cuentapersonal:"ruben@facebook.com", cuentaprofesional:"rubenpro@facebook.com"}, instagram:"@ruben"} var persona1 = {nombre:"Ruben",edad:25}; var persona2 = {nombre:"Ale", edad:20, social:redessociales, getEdad:function(){ return this.edad;} }; console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1 = JSON.parse(JSON.stringify(persona2)); console.log("Persona1:",persona1,"\nPersona2:",persona2); persona2.social.facebook.cuentapersonal = "NUEVACUENTA"; console.log("Persona1:",persona1,"\nPersona2:",persona2);
Perfecto… ya nos copia el valor del objeto redessociales dentro de un nuevo objeto y son independientes uno de otro ….
pero…. ¿la función getEdad() donde esta en Persona1?
JSON.parse y JSON.stringify no copia las funciones…. Tampoco nos vale!!!
Método 4: Función Recursiva
function deepClone(object){ var clone = {}; for ( var key in object){ var value = object[key]; if(typeof(value) != 'object'){ clone[key] = value; } else{ clone[key] = deepClone(value); } } return clone; } var redessociales = {facebook:{ cuentapersonal:"ruben@facebook.com", cuentaprofesional:"rubenpro@facebook.com"}, instagram:"@ruben"} var persona1 = {nombre:"Ruben",edad:25}; var persona2 = {nombre:"Ale", edad:20, social:redessociales, getEdad:function(){ return this.edad;} }; console.log("Persona1:",persona1,"\nPersona2:",persona2); persona1 = deepClone(persona2); console.log("Persona1:",persona1,"\nPersona2:",persona2); persona2.social.facebook.cuentapersonal = "NUEVACUENTA"; console.log("Persona1:",persona1,"\nPersona2:",persona2);
Ahora si hemos conseguido lo que buscabamos, crear un objecto totalmente independiente al otro.
**Recordamos: ¿Que es un Objeto en Javascript? Un objecto es un conjunto de pares clave/valor. En otros lenguajes lo llamaras diccionario, hash o array asociativo.
Explicación Clonado de Objecto de Carlos Blé: