有没有办法复制 javascript 中的对象数组?

Is there a way to copy an array of objects in javascript?

这可能是我在 javascript 方面的无能造成的问题,因为我是这门语言的新手,但到目前为止我还没有找到可行的解决方案。

问题是我想制作一个对象数组的副本数组,然后更改副本数组中的数据而不更改初始对象的值数组,最后再次将复制数组分配给初始数组,这样我就可以在另一个具有初始值的函数中再次使用它。

我制作了一个简单的程序,其中包含两个 类 - Country 包含一些属性和更改其中一个属性的函数,World 包含一组国家和更改所有数据的函数数组中的国家。我创建一个 World 实例,调用 changeAllCountriesData 函数 最后打印 countries 数组和 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});
})

上面那个returns每次计算后都是NaN。

4.

this.countries.forEach(c => {
      let obj = Object.assign({}, c);
      this.copyData.push(obj);
})

5.

this.copyData = this.countries.concat();

None个方法复制了数组,原数组不变,或者计算不返回NaN

在JS中,对象是通过引用来复制的。因此,当您 .slice(0) 时,您是部分正确的,但问题是,内部值是对象。所以新数组有以前的值。

现在您也可以尝试 .map(obj => ({ ...obj }) ) 但这将不起作用,因为对象传播将创建一个具有属性但没有方法的新对象。所以任何方法,比如 changeData 都不会出现在这个对象上。因此,您必须为 class.

创建一个复制机制

尝试更新到

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);

我正要发表评论,但我还没有足够的积分。

  1. changeAllCountriesData() 中(在 class World 中)您试图调用 changeDate() 函数,它是 class 国家/地区中的本地函数。我不确定 class World 是否可以直接访问另一个 class 的本地函数。在将 class 分配给变量 varletconst 后,您可以在 class 中调用函数。 示例:

    const codeland = new Country('USA', 123, 456);

    codeland.changeData();

现在,codeland 是全局变量。现在,您可以在 class 世界中通过 codeland 变量访问 changeData() 函数。

我不擅长JavaScript,我相信一定有更简单的方法!

关于复制数组,方法#1 和#3 是正确的。 (不确定方法 #2 和 #4。方法 #5 将 countries 连接到 copyData。)它们 return NaN,因为当您从一个国家复制数据时,两个国家和 copyData 都是空的阵列到另一个。因此,它是 NaN(或未定义)。

希望对您有所帮助!