2012-12-20 17 views
6

Questa è la continuazione di My Old QuestionPosso conservare una copia di un oggetto, all'interno di tale oggetto quando il suo creato - Continua:

Questa è la mia funzione che crea un nuovo oggetto studente:

function student(id, name, marks, mob, home){ 
    this.id = id; 
    this.name = name; 
    this.marks = marks; 
    this.contacts = {}; 
    this.contacts.mob = mob; 
    this.contacts.home = home; 

    this.toContactDetailsString = function(){ 
     return this.name +':'+ this.mob +', '+ this.home 
    } 
} 

Vorrei creare una copia dell'oggetto quando viene inizializzato all'interno di tale oggetto: sono arrivato fino a questo:

function student(id, name, marks, mob, home){ 
    this.id = id; 
    this.name = name; 
    this.marks = marks; 
    this.contacts = {}; 
    this.contacts.mob = mob; 
    this.contacts.home = home; 

    this.toContactDetailsString = function(){ 
     return this.name +':'+ this.mob +', '+ this.home 
    } 
    this.baseCopy = this; //Not sure about this part 
} 

Ma il problema è che mi dà un ciclo infinito di copie dell'oggetto corrente in baseCopy; Inoltre, si aggiorna automaticamente ogni volta che aggiorno qualsiasi attributo del mio oggetto.

1. In che modo è possibile che sia possibile conservare una copia di un oggetto con i valori iniziali all'interno di quell'oggetto al momento della sua creazione?

2. E 'possibile non copiare le funzioni

3. Sono molto curioso di sapere se questo è possibile, senza i nomi degli attributi difficili codifica e utilizzando puro JS

+0

Non si assegna una copia dell'oggetto a "baseCopy" ma un riferimento. Nessuna copia è stata eseguita, ecco perché "baseCopy" è sempre "aggiornato". Dai un'occhiata a http://api.jquery.com/jQuery.extend/ per avere un'idea di come ottenere una copia effettiva. – Niko

+0

'this' sembra riferirsi all'oggetto' window' in questo contesto. – Stefan

+0

Quindi, qualcuna delle risposte pubblicate ha funzionato per te? – Cerbrus

risposta

3

Più o meno come la mia risposta alla tua domanda precedente, è possibile utilizzare questo codice per fare una copia dell'oggetto ed è annidato proprietà, pur non copia-ing sue funzioni:

function student(id, name, marks, mob, home){ 
    this.id = id; 
    this.name = name; 
    this.marks = marks; 
    this.contacts = {}; 
    this.contacts.mob = mob; 
    this.contacts.home = home; 

    this.toContactDetailsString = function(){ 
     return this.name +':'+ this.mob +', '+ this.home 
    } 

    // Copy the object to baseCopy 
    this.baseCopy = clone(this); // "clone" `this.baseCopy` 
} 

function clone(obj){ 
    if(obj == null || typeof(obj) != 'object'){ // If the current parameter is not a object (So has no properties), return it; 
     return obj; 
    } 

    var temp = {}; 
    for(var key in obj){ // Loop through all properties on a object 
     if(obj.hasOwnProperty(key) && !(obj[key] instanceof Function)){ // Object.prototype fallback. Also, don't copy the property if it's a function. 
      temp[key] = clone(obj[key]); 
     } 
    } 
    return temp; 
} 

var s = new student(1, 'Jack', [5,7], 1234567890, 0987654321); 
s.marks = s.marks.concat([6,8]); // Jack's gotten 2 new marks. 

console.log(s.name + "'s marks were: ", s.baseCopy.marks); 
// Jack's marks were: [5, 7] 
console.log(s.name + "'s marks are: ", s.marks); 
// Jack's marks are: [5, 7, 6, 8] 
console.log(s.baseCopy.toContactDetailsString); // check if the function was copied. 
// undefined 
console.log(s.baseCopy.contacts.mob); 
// 1234567890 

(I' Lavorerò sulla copia profonda per un secondo)

La copia "profonda" dovrebbe funzionare ora.

3

non si sta creando una copia dicendo

this.baseCopy = this;, si sta solo impostando il riferimento a questa variabile interna. Così baseCopy è anche rivolta al medesimo oggetto

È necessario creare un metodo che restituirà un nuovo oggetto studente oggetto studente passato e quindi memorizzare che, come BaseCopy

1
this.baseCopy = new student(id, name, marks); 

Il tuo modo fa solo un riferimento circolare. Utilizzare new per creare un'istanza di un nuovo oggetto.

L'utilizzo di questo probabilmente andrà comunque in una ricorsione infinita.

È possibile aggirare questo come questo:

function student(id, name, marks, flag) { 
    // usual code... 
    // And: 
    if (!flag) { 
     this.baseCopy = new student(id, name, marks, true); 
    } 
} 

questo modo, solo lo studente superiore ha una baseCopy.

+0

Probabilmente non funzionerà. Quando ne aggiungi una nuova con gli stessi input ... la nuova copia probabilmente ne aggiungerà un'altra ... che ne farà un'altra copia. – user1600124

+0

@ user1600124 modificato per tenerne conto :) –

+0

in questo modo .. baseCopy è ancora un'istanza di studente e dovrebbe avere le funzioni definite in esso – user1600124

1

Beh ...

this.baseCopy = this; 

sostanzialmente significa che baseCopy dell'oggetto è l'oggetto stesso. Quindi:

var abc = new student(someId, someName, someMarks); 

abc e abc.baseCopy puntano effettivamente allo stesso oggetto. Che cosa si può fare è probabilmente cambiare baseCopy a:

this.baseCopy = { id: id, name: name, marks: marks, contact: {mob:mob, home: home}} 

Fondamentalmente creare manualmente una copia degli ingressi in un oggetto. Tenere presente che se uno qualsiasi degli input è un tipo di riferimento, la copia punta ancora allo stesso oggetto dell'originale.

+0

Hai ancora bisogno dei metodi. –

+0

Ha chiesto se è possibile non copiare le funzioni ... – user1600124

+0

Oh, giusto. Colpa mia :-) –

Problemi correlati