2012-12-20 35 views
6

這是My Old Question我可以保持一個對象的副本,該對象內部時,它的創建 - 續:

延續這是我的函數,它創建了一個新的學生對象:

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 
    } 
} 

我想在對象內部初始化時創建一個對象的副本: 我想出了這個:

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 
} 

但問題是它給了我一個無限循環的拷貝當前對象在baseCopy中;並且,當我更新我的對象的任何屬性時,它也會自動更新。

1.如何在創建對象時保留具有初始值的對象的副本?

2.是否有可能不使用純JS

+0

您不會將對象的副本分配給「baseCopy」,而只是引用。沒有複製完成,這就是爲什麼「baseCopy」總是「最新」。查看http://api.jquery.com/jQuery.extend/以瞭解如何獲得實際副本。 – Niko

+0

'this'似乎指的是這個上下文中的'window'對象。 – Stefan

+0

那麼,是否有任何答案張貼爲你工作? – Cerbrus

回答

3

很像我在你前面的問題的答案,你可以使用這個代碼,以使對象的副本,它的嵌套屬性,而不是複製-ING它的功能:

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」將在深層複製上工作一秒)

「深」副本現在應該可以工作。

3
複製功能

3.我很好奇,想知道這是可能的,而不硬編碼的屬性名稱和

你沒有創建一個副本說

this.baseCopy = this;,你只是設置這個內部變量的引用。所以baseCopy也指向同一個對象

您需要創建將從通過學生對象返回一個新的學生對象,然後存儲爲BaseCopy

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

你的方式只是讓循環引用的方法。使用new實例化一個新對象。

雖然使用這可能會進入無限遞歸。

你可以這樣繞過此:

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

這種方式,只有最上面的學生有一個baseCopy。

+0

這可能不起作用。當你使用相同的輸入新建一個副本時,新副本可能會新增另一個副本......這將會新增另一個副本。 – user1600124

+0

@ user1600124編輯考慮到這一點:) –

+0

這種方式.. baseCopy仍然是學生的一個實例,應該有它定義的功能 – user1600124

1

嗯......

this.baseCopy = this; 

基本上意味着該對象的baseCopy是對象本身。所以:

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

abc和abc.baseCopy實際上指向同一個對象。 你可以做的是可能會改變baseCopy到:

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

基本上手動創建的輸入進副本的對象。 請注意,如果有任何輸入是參考類型,則副本仍將指向與原始對象相同的對象。

+0

你仍然需要這些方法。 –

+0

他問是否可以不復制功能... – user1600124

+0

哦對。我的錯 :-) –

相關問題