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

标签 javascript arrays object javascript-objects arrayobject

这可能是由于我对 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/

相关文章:

javascript - Vue.js 在组件/应用程序之外观察 DOM 元素属性

javascript - Karma-Browserify + Karma-Coverage 的问题

c - 如何创建一个接口(interface)来为 fortran 转换 c 字符数组

java - 如何使用 Java 将 json 数组转换为 CSV 文件

c++ - 将一个类对象的指针赋值给另一个类对象c++

javascript - 访问对象内部的数组

javascript - .addClass 错过了在 JavaScript 中使用 for 循环的最终动态创建的元素?

c++ - 如何为 Boost Multi-Array 释放内存?

c# - 测试一个对象不是一个类型

javascript - 未打开主页时使标题变小?