有没有办法在javascript中复制一个对象数组?

这可能是我对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.cates.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);

给TA打赏
共{{data.count}}人
人已打赏
未分类

使正方形透明的一部分-翩翩起舞

2022-9-9 4:46:22

未分类

在SQL查询中自动获取待用列(HibernateMybatishome-made)?- 创建一个库的想法

2022-9-9 4:57:17

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索