2010-09-22 18 views
16

Eventuali duplicati:
How to clone js object?Clonazione di un oggetto JavaScript?

Questo è un altro modo per creare un oggetto JavaScript (con oggetto la notazione letterale al posto della funzione):

user = { 
    name: "Foo", 
    email: "[email protected]" 
} 

Esiste un modo clonare questo oggetto o è un singleton?

+3

Oggetto JavaScript! = Oggetto JSON. L'esempio che hai fornito è un oggetto JavaScript letterale; Ho aggiornato il tuo post di conseguenza. –

+0

buona domanda! Penserò sempre che user2 = user farà una copia, ma no. – Topera

+1

"risposta" più breve: sì e sì. ;) –

risposta

26

Prova questo:

var clone = (function(){ 
    return function (obj) { Clone.prototype=obj; return new Clone() }; 
    function Clone(){} 
}()); 

Ecco cosa sta succedendo.

  • Clone è un fittizio costruttore.
  • Assegniamo l'oggetto che vogliamo clonare al prototipo del costruttore clone.
  • Chiamiamo Clone usando 'nuovo', quindi l'oggetto costruito ha l'oggetto originale come prototipo del suo costruttore aka (non standard) __proto__.

L'oggetto clonato condividerà tutte le proprietà dell'oggetto originale senza alcuna copia di ciò che viene fatto. Se le proprietà dell'oggetto clonato vengono assegnate a nuovi valori, non interferiranno con l'oggetto originale. E non è richiesta alcuna manomissione dei built-in.

Ricordare che una proprietà dell'oggetto dell'oggetto appena creato farà riferimento allo stesso oggetto dell'omonima proprietà dell'oggetto clonato. Assegnare un nuovo valore a una proprietà del clone non interferirà con l'originale, ma assegnerà i valori alle proprietà dell'oggetto del clone.


Prova questa in consolle cromata o Firebug:

var user = { 
    name: "Foo", 
    email: "[email protected]" 
} 

var clonedUser = clone(user); 

console.dir(clonedUser); 

Una spiegazione dettagliata di questa tecnica di clonazione può essere trovato here.

+2

'utente = {nome:" ", email:" ", obj: {a:" A "}}; clonedUser = clone (utente); ',' clonedUser.obj.a = "B"; 'troverai' user.obj.a == "B" ' – vol7ron

+0

Anche questo sembra molto simile alla risposta di Chris J. – vol7ron

+0

vol7ron: sì, perché user.obj e clonedUser.obj si riferiscono allo stesso oggetto. Assegnare un nuovo valore alla proprietà 'obj' di NewUser non mostrerà questo comportamento. La richiesta era per un clone, non una copia e non una copia profonda. Vedi il link alla fine della mia risposta. –

2

La maggior parte dei framework javascript ha un buon supporto per la clonazione di oggetti.

var a= {'key':'value'}; 
var b= jQuery.extend(true, {}, a); 
+0

concordato: underscorejs ha anche un metodo clone http://underscorejs.org/#clone – dreftymac

10

È possibile utilizzare l'oggetto JSON (presente nei browser moderni):

var user = {name: "Foo", email: "[email protected]" } 
var user2 = JSON.parse(JSON.stringify(user)) 

user2.name = "Bar"; 
alert(user.name + " " + user2.name); // Foo Bar 

veda in jsfiddle.


EDIT

Se avete bisogno di questo nei browser meno recenti, vedere http://www.json.org/js.html.

+1

hmm ... non sta andando verso il basso, ma questo è solo sciocco, secondo me. prima di tutto, se hai intenzione di usare JSON, dovrai includere json2.js nella tua pagina perché ci sono ancora dei browser correnti senza json nativi e ci saranno in uso quelli che non sono correnti da un po 'di tempo. Scrivi o prendi in prestito un'implementazione di estensione o includi una libreria che ne ha uno. –

+0

Sto solo dando un altro modo per farlo. Se un sito ha già json2.js, funziona. – Topera

+1

Se un oggetto ha sia 'proprietà' che' metodi', allora amico mio, usando questo stile JSON, 'metodi' sono ** non clonati ** –

4

mi piace usare questo:

if (typeof Object.create !== 'function') { 
    Object.create = function (o) { 
     var F = function() {}; 
     F.prototype = o; 
    return new F(); 
    }; 
} 

poi qualsiasi oggetto che voglio clonare può essere fatto come:

user = { 
    name: "Foo", 
    email: "[email protected]" 
}; 
var user2 = Object.create(user); 

Come mostrato in (o simili a) JavaScript le parti buone

+1

Non dovresti farlo; vedi [risposta di Kangax] (http://stackoverflow.com/questions/3075308/what-modernizer-scripts-exist-for-the-new-ecmascript-5-functions/3075818#3075818) –

+2

@Marcel Grazie per aver segnalato che su. Lascio la mia risposta così com'è e raccomando la spiegazione di Kangax come una buona lettura. –

+0

@ Marcel/Chris +1; La risposta di Kangax è solo che creare non ha due proprietà ovunque. La mia sensazione è che tutti usassero questo metodo, quindi costringerebbe i venditori a conformarsi agli standard. Inizialmente non usavo FF perché non mostrava tutto correttamente, ora il web è diventato più intelligente e FF ha apportato modifiche per funzionare meglio in modalità quirks. Lo stesso sarà vero se i programmatori si limitano agli standard e spingono i browser che li accettano. – vol7ron

0
Object.prototype.clone = function clone(obj) { 
          obj = obj || this; 
          var new_obj = {}; 

          for(var p in obj) { 
          if (obj.hasOwnProperty(p)) { 
           if(obj[p] !== null && typeof(obj[p]) === "object") { 
           new_obj[p] = clone(obj[p]); 
           } 
           else { 
           new_obj[p] = obj[p]; 
           } 
          } 
          } 

          return new_obj; 
         }; 


/* Example */ 
var foo = { 
    name: "Foo" 
    , email: "[email protected]" 
    , obj: {a:"A",b:"B"} 
}; 

var bar = foo.clone(); 
bar.name = "Bar"; 
bar.obj.b = "C"; 


// foo and bar should have a different 'name' 
// foo and bar should retain the same email 
// foo and bar should have different values for <foo/bar>['obj']['b'] 
// foo and bar should have the same values for <foo/bar>['obj']['a'] 
console.dir(foo); 
console.dir(bar); 
+3

no no no ... non scherzare mai con Object.prototype, spezzerai tutto: P –

+2

che non è corretto, a meno che tu non sia uno dei droni che usano 'JQuery', quindi non scherzi mai e dimentica come fare nulla. – vol7ron

+2

Non ti arrabbiare. Evito generalmente jQuery. Due cose, però ... 1, questo non è un clone, è una copia. Il nome 'clonazione' è associato a questo tipo di tecnica: http://oranlooney.com/functional-javascript/ –