2013-06-06 21 views
20

E 'sulle migliori pratiche quando è necessario copiare l'oggetto in javascript ..Qual è la differenza tra underscore clone() e simple '='?

Ad esempio:

Ho un oggetto { name: 'Dodo', method: function() { console.log(this.name) }};

Ho bisogno di creare una copia di esso:

var obj = { name: 'Dodo', method: function() { console.log(this.name) } }; 
// what is better? 
var copyUnderscore = _(obj).clone(); 
var copySimple = obj; 

Qual è il modo migliore? Grazie!

+5

Fanno cose diverse, quindi dovrebbe essere abbastanza ovvio. O non hai capito la differenza? – Bergi

+1

'simpleCopy' contiene solo un riferimento. –

+0

@Bergi sembra che capisca, ma ho bisogno semplicemente di un altro alias .. nel mio caso è ancora più complicato avere '' obj.objChild'' e voglio assegnare '' obj.childAlias ​​= obj.objChild'', tutto funziona bene , ma voglio semplicemente sapere se è buono – Kosmetika

risposta

77

_.clone è completamente diverso dall'assegnazione.

_.clone crea un nuovo oggetto e copia ogni valore dall'originale al nuovo oggetto.

Un'assegnazione punta semplicemente una variabile sull'oggetto che esiste già.

Supponi di avere un cucciolo. Chiamiamolo Rex.

Se stai discutendo di Rex con qualcuno lo chiamerai Rex, o forse "il Cane". Entrambi sono riferimenti all'animale in questione. Un'assegnazione è analoga a usare frasi diverse per il vostro animale domestico:

rex = { 
 
    type: 'Dog', 
 
    age: '12 Weeks', 
 
    name: "Rex", 
 
    fixed: false, 
 
    fix: function() { 
 
    this.fixed = true; 
 
    console.log(this.name + " Fixed."); 
 
    } 
 
}; 
 
theDog = rex; 
 

 
// Note the use of `===`, which checks for object identity. 
 
// Assignment (as above) is the whole point of `===` 
 
if (theDog === rex) { 
 
    alert("The Dog is the Same as Rex"); 
 
}

Quando si cambia qualcosa su di uno, cambia per entrambi i riferimenti. Quindi, si supponga di "fissare" Rex:

rex = { 
 
    type: 'Dog', 
 
    age: '12 Weeks', 
 
    name: "Rex", 
 
    fixed: false, 
 
    fix: function() { 
 
    this.fixed = true; 
 
    console.log(this.name + " Fixed."); 
 
    } 
 
}; 
 
theDog = rex; 
 
rex.fix(); 
 

 
alert("The Dog is " + (theDog.fixed ? "" : "not ") + "fixed"); 
 
alert("Rex is " + (rex.fixed ? "" : "not ") + "fixed");

theDog è fisso.

Ora supponiamo di aver clonato Rex. (Facciamo finta che non sia ancora fissato per il gusto della discussione).

rex = { 
 
    type: 'Dog', 
 
    age: '12 Weeks', 
 
    name: "Rex", 
 
    fixed: false, 
 
    fix: function() { 
 
    this.fixed = true; 
 
    console.log(this.name + " Fixed."); 
 
    } 
 
}; 
 
theDog = rex; 
 
otherDog = _.clone(rex); 
 

 
console.log(theDog); 
 
console.log(rex); 
 
console.log(otherDog); 
 

 
var message = rex === theDog ? "Rex is the same as the dog" : "Rex and the dog are different"; 
 
message += "\n"; 
 
message += rex === otherDog ? "Rex is the same as the other dog" : "Rex is different from the other dog"; 
 
message += "\n"; 
 
message += rex.fixed ? "Rex is fixed" : "Rex is not fixed"; 
 
message += "\n"; 
 
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed"; 
 

 
alert(message); 
 

 
otherDog.fix(); 
 

 
message = rex.fixed ? "Rex is fixed" : "Rex is not fixed"; 
 
message += "\n"; 
 
message += otherDog.fixed ? "Other dog is fixed" : "Other dog is not fixed"; 
 
alert(message);
<script src="http://underscorejs.org/underscore-min.js"></script>

Ogni valore da rex è stato copiato nella otherDog. Miracolosamente, "otherDog" è nato all'età di 12 settimane. Ma fissando uno sarà non correggere l'altro.

Ora dal rex e theDog sono lo stesso cane, nessuno dei due è fisso. Tuttavia, otherDogè corretto. Lui è un clone, non lo stesso animale.

Ci sono alcune sottigliezze da cui fare attenzione. _.clone non copia profondamente. Ciò significa che qualsiasi oggetto o matrice che è un valore nell'oggetto clonato viene copiato dall'assegnazione al nuovo oggetto (vedere il primo frammento per una revisione di cosa significa).

Questo significa che se rex aveva una proprietà mother che era un oggetto che rappresenta la madre sarebbe condivisa tra rex e otherDog. Qualsiasi modifica alla madre di rex verrebbe propagata a otherDog. Questo non è molto diverso dalla vita reale; la madre biologica è la stessa cosa.

EDIT

Come un'altra nota miracolo: la clonazione di un cane fissa produce un altro cane fissa. È qui che la metafora biologica si rompe.

+0

grazie Christopher, ottima risposta;) – Kosmetika

+8

riferimenti e puntatori sono complicati. Non scoraggiarti, trova analogie nella vita reale finché non lo ottieni ... può volerci un po ', ma è estremamente importante. Un buon lavoro nel riconoscere che non hai capito la differenza. – Crisfole

+5

Non dimenticare il ['underscore.clone (obj)'] (http://underscorejs.org/#clone) ti dà solo una copia superficiale –

Problemi correlati