【问题标题】:Making changes to a copied array, updates the original?对复制的数组进行更改会更新原始数组吗?
【发布时间】:2018-01-30 19:46:53
【问题描述】:

我有一个对象数组:

 let users = [{name: 'john', address: '10 king street'}, ....];

我通过以下方式复制这个数组:

let usersCopy = users.slice(0);

如果我这样做了

usersCopy[0].name = jeff;

它还在原始用户数组上更新了这个:

console.log(usersCopy[0].name) //jeff
console.log(users[0].name) //jeff

我期待看到:

console.log(usersCopy[0].name) //jeff
console.log(users[0].name) //john

【问题讨论】:

  • 但我更改的是副本而不是原件。
  • 就像“复制”中所说,这是一个“浅拷贝”。在您的数组中,您有另一个不会被克隆的对象(一个 json)。
  • 副本谈到将相同的数组分配给不同的变量,这是一个不同的问题。

标签: javascript


【解决方案1】:

那是因为[].slice() 做了一个 复制,这意味着你得到一个新数组,但它不会克隆下面的对象。因此,users[0] === usersCopy[0],因为它们是对同一个对象的相同引用。

您需要完全替换 usersCopy[0]。例如:

usersCopy[0] = {...usersCopy[0], name: 'jeff'}

这将创建一个新对象,其中包含 usersCopy[0] 的所有内容。

【讨论】:

  • 如何不浅拷贝数组中的对象?
  • 您可以使用 lodash 的 _.cloneDeep 或其他一些深度克隆方法。但一般来说,您应该避免深度克隆任意对象,因为它在性能方面相当昂贵。
【解决方案2】:

编辑:如下所述,此答案不正确

这是从原始数组创建单独数组的另一种方法,以便您可以修改 clone

const users = [{name: 'John', address: '10 king street'}];
const clone = new Array(users);

clone[0].name = 'Jeff';

console.log(clone[0].name) //jeff
console.log(users[0].name) //john

【讨论】:

  • clone 现在是一个嵌套数组,有一个附加属性name 等于Jeff,如果你尝试记录clone[0].address,你会发现它是未定义的。跨度>
猜你喜欢
  • 2018-01-12
  • 2021-01-18
  • 2011-01-20
  • 2021-11-24
  • 2021-11-03
  • 1970-01-01
  • 2014-03-18
  • 2020-08-09
  • 1970-01-01
相关资源
最近更新 更多