2017-02-12 48 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