2017-02-12 78 views
0

我想刷新一些數據,用完全替換它的對象具有一組具有空值的鍵。替換一個空的原型對象

例如

const sportPrototype = { 
    name: '', 
    players: '', 
    displacement: '', 
    points: '', 
    leagues: [] 
} 

var profileScratchpadOne = { 
    sportScratchpad: { 
    name: 'Soccer', 
    players: '16', 
    displacement: 'Foot', 
    points: 'unlimited', 
    leagues: ["Fifa"] 
    } 
} 

profileScratchpadOne.sportScratchpad = sportPrototype 
profileScratchpadTwo.sportScratchpad = sportPrototype 

只要在任一sportScratchpad個價值得到改變,它在這兩個profileScratchpadOneprofileScratchpadTwo

我想通過一個參考。

我調查了傳播運算符,原型,構造函數,還沒有找到一個防彈,簡潔的方法。

什麼是最簡潔的方式來解決這個問題,並每次傳遞一個新對象?

+0

如果一個淺拷貝就足夠了(例如,除了聯盟屬性 - 根據您的期望),然後'= Object.assign({},sportPrototype);' – trincot

回答

1

正如其他人所說,是Object.assign()創建對象的淺拷貝的一種方式。另一種選擇是使用Object.create(),其中「包裝」的對象,以便爲新對象的屬性分配值將不會覆蓋原型的屬性:

const sportPrototype = { 
 
    name: '', 
 
    players: '', 
 
    displacement: '', 
 
    points: '', 
 
    leagues: [] 
 
} 
 

 
var profileScratchpadOne = { 
 
    sportScratchpad: { 
 
    name: 'Soccer', 
 
    players: '16', 
 
    displacement: 'Foot', 
 
    points: 'unlimited', 
 
    leagues: ["Fifa"] 
 
    } 
 
} 
 

 
var profileScratchpadTwo = {} 
 

 
profileScratchpadOne.sportScratchpad = Object.create(sportPrototype) 
 
profileScratchpadTwo.sportScratchpad = Object.create(sportPrototype) 
 

 
console.log(sportPrototype.name); 
 
console.log(profileScratchpadOne.sportScratchpad.name); 
 
console.log(profileScratchpadTwo.sportScratchpad.name); 
 

 
profileScratchpadOne.sportScratchpad.name = 'Jai Alai' 
 
profileScratchpadTwo.sportScratchpad.name = 'Curling' 
 

 
console.log(sportPrototype.name); 
 
console.log(profileScratchpadOne.sportScratchpad.name); 
 
console.log(profileScratchpadTwo.sportScratchpad.name);

然而,無論Object.createObject.assign將有leagues屬性的問題,因爲它是一個引用類型,因此將在所有副本之間共享(如果您改變它)(通過添加元素等)。出於這個原因,當你想複製原型時,你基本上需要爲leagues(和任何其他引用類型屬性)創建一個新的空數組。

你可以照顧這與工廠的功能,如:

function sportDefaults() { 
    var newObj = Object.create(sportPrototype); 
    newObj.leagues = []; 

    return newObj; 
} 

profileScratchpadOne.sportScratchpad = sportDefaults() 

編輯:Object.create的好處是,只有一個創建你的原始樣機和新屬性的副本需要,這節省了內存。如果你不是所有人都關心內存,那麼你可以創建一個函數,每次都會返回一個原型的全新副本。這將回避上述問題,引用類型:

function sportDefaults() { 
 
    return { 
 
    name: '', 
 
    players: '', 
 
    displacement: '', 
 
    points: '', 
 
    leagues: [] 
 
    } 
 
} 
 

 
var profileScratchpadOne = {} 
 
var profileScratchpadTwo = {} 
 

 
profileScratchpadOne.sportScratchpad = sportDefaults() 
 
profileScratchpadTwo.sportScratchpad = sportDefaults() 
 

 
console.log('- before assignment') 
 
console.log(profileScratchpadOne.sportScratchpad.name) 
 
console.log(profileScratchpadTwo.sportScratchpad.name) 
 

 
profileScratchpadOne.sportScratchpad.name = 'Jai Alai' 
 
profileScratchpadTwo.sportScratchpad.name = 'Curling' 
 

 
console.log('- after assignment') 
 
console.log(profileScratchpadOne.sportScratchpad.name) 
 
console.log(profileScratchpadTwo.sportScratchpad.name)

+0

感謝您的最佳尋址用例。像Array.create? – softcode

+1

@softcode你可以使用一個空的數組:'profileScratchpadOne.sportScrachpad.leagues = []'。 – JLRishe

+1

@softcode增加了一個額外的附加方法,你可以使用。 – JLRishe

1

編輯:由於sportPrototype中至少有一個對象(數組),淺拷貝不是這裏的正確選擇。最簡單的深層副本可以選擇:

function deepCopy(o) { 
    return JSON.parse(JSON.stringify(o)); 
} 

const sportPrototype = { 
    name: '', 
    players: '', 
    displacement: '', 
    points: '', 
    leagues: [] 
} 

var profileScratchpadOne = { 
    sportScratchpad: { 
    name: 'Soccer', 
    players: '16', 
    displacement: 'Foot', 
    points: 'unlimited', 
    leagues: ["Fifa"] 
    } 
} 

profileScratchpadOne.sportScratchpad = deepCopy(sportPrototype); 
profileScratchpadTwo.sportScratchpad = deepCopy(sportPrototype); 
2

雖然Object.assign就在這裏工作,對象仍然會共享相同的leagues陣列。只有原始類型的屬性將生活在不同的生活中。你可以發現,執行深拷貝功能,但我認爲在這種情況下,你可以使用構造模式:

function SportPrototype() { 
    this.name = ''; 
    this.players = ''; 
    this.displacement = ''; 
    this.points = ''; 
    this.leagues = []; 
} 

var profileScratchpadOne = {}; 
var profileScratchpadTwo = {}; 

var o = new SportPrototype(); 
o.name = 'Soccer'; 
o.players = '16'; 
o.displacement = 'Foot'; 
o.points = 'unlimited'; 
o.leagues = ["Fifa"]; 
profileScratchpadOne.sportScratchpad = o; 

profileScratchpadOne.sportScratchpad = new SportPrototype(); 
profileScratchpadTwo.sportScratchpad = new SportPrototype(); 

現在最後兩個賦值將產生完全獨立的對象。

+0

很抱歉,您看到您從我的答案中刪除了接受。有問題嗎? – trincot