这可能是由于我对 javascript 的不熟练造成的,因为我是该语言的新手,但到目前为止我还没有找到可行的解决方案。
问题是我想创建一个对象数组的复制数组,然后更改复制数组中的数据而不更改初始数组中对象的值,最后分配再次将数组复制到初始数组,以便我可以在另一个具有初始值的函数中再次使用它。
我制作了一个简单的程序,其中包含两个类 - Country 包含一些属性和一个用于更改这些属性之一的函数,而 World 包含一个国家数组和一个用于更改数组中所有国家/地区数据的函数。我创建一个 World 实例,调用changeAllCountriesData 函数 最后打印国家数组和 copyData 数组的值。正如你所看到的,它们都发生了变化,我不确定原因。
class Country{
name; area; population;
constructor(name, area, population){
this.name = name;
this.area = area;
this.population = population;
}
changeData(){
this.population += Math.round(this.population * 0.02);
}
}
class World{
countries = [];
copyData = [];
constructor(){
this.loadData();
this.copyData = this.countries.slice(0);
}
loadData(){
this.countries.push(new Country("Denmark", 41990, 5839809));
this.countries.push(new Country("Germany", 349360, 83159604));
this.countries.push(new Country("Netherlands", 33690, 17342709));
}
changeAllCountriesData(){
this.copyData.forEach(c => {
c.changeData();
})
}
}
console.log("Initial information for the population: 5839809, 83159604, 17342709")
w = new World();
w.changeAllCountriesData();
console.log("countries array:")
console.log(w.countries);
console.log("copyData array:")
console.log(w.copyData);
我尝试过的其他方法来代替 this.copyData = this.countries.slice(0):
1.
this.copyData = [...this.countries]
2.
this.copyArray = Array.from(this.countries);
this.copyData = copyArray[0];
3.
this.countries.forEach(c => {
this.copyData.push({...c});
})
上面的每次计算后都会返回 NaN。
4.
this.countries.forEach(c => {
let obj = Object.assign({}, c);
this.copyData.push(obj);
})
5.
this.copyData = this.countries.concat();
这些方法都没有以初始数组保持不变或在不返回 NaN 的情况下进行计算的方式创建复制数组。
最佳答案
在 JS 中,对象是通过引用来复制的。因此,当您这样 .slice(0)
时,您是部分正确的,但问题是,内部值是对象。所以新数组具有以前的值。
现在您也可以尝试 .map(obj => ({ ...obj }) )
但这不起作用,因为对象传播将创建一个具有属性但不具有方法的新对象。因此任何方法,例如 changeData
都不会出现在该对象上。因此,您必须为您的类创建一个复制机制。
尝试更新到
cloneObject() {
const {name, area, population} = this;
return new Country(name, area, population)
}
...
this.copyData = this.countries.map( (obj) => obj.cloneObject() );
注意:您可以扩展此函数的功能。您可以添加参数来覆盖这些值。这将允许您一次性执行多个操作:
cloneObject( overrides ) {
const { name, area, population } = { ...this, ...overrides };
return new Country(name, area, population)
}
...
this.copyData = this.countries.map( (obj) => obj.cloneObject({ name: 'Hello World' }) );
示例代码:
class Country{
name; area; population;
constructor(name, area, population){
this.name = name;
this.area = area;
this.population = population;
}
cloneObject() {
const {name, area, population} = this;
return new Country(name, area, population)
}
changeData(){
this.population += Math.round(this.population * 0.02);
}
}
class World{
countries = [];
copyData = [];
constructor(){
this.loadData();
this.copyData = this.countries.map( (obj) => obj.cloneObject() );
}
loadData(){
this.countries.push(new Country("Denmark", 41990, 5839809));
this.countries.push(new Country("Germany", 349360, 83159604));
this.countries.push(new Country("Netherlands", 33690, 17342709));
}
changeAllCountriesData(){
this.copyData.forEach(c => {
c.changeData();
})
}
}
console.log("Initial information for the population: 5839809, 83159604, 17342709")
w = new World();
w.changeAllCountriesData();
console.log("countries array:")
console.log(w.countries);
console.log("copyData array:")
console.log(w.copyData);
关于javascript - 有没有办法在javascript中复制对象数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61409087/