【问题标题】:Understanding spread operator in JS理解 JS 中的扩展运算符
【发布时间】:2019-05-08 17:02:12
【问题描述】:

所以我尝试了一个简单的例子:

  const original = [
     {id: 0, color: "red"},
     {id: 1, color: "blue"}
      ]
  const copy = [...original]

  copy[0] = {id:2, color:"red"}
  copy[1].id = 2
  console.log(original)
  console.log(copy)

我得到的结果令人困惑:

   Array [Object { id: 0, color: "red" }, Object { id: 2, color: "blue" }]
   Array [Object { id: 2, color: "red" }, Object { id: 2, color: "blue" }]

当我更改整个对象时,更改只发生在副本数组中。

那么为什么 copy[1].id = 2 实际上也改变了原始数组而不仅仅是复制数组中的一个键??

【问题讨论】:

  • [...array] 创建一个包装原始对象的新数组。所以包含的数组引用与原始是唯一的,但数组中的对象是原始对象
  • 第一件事:它看起来像被称为“运算符”的东西,但它不是运算符。
  • 传播只是一个副本。它是对相同旧对象的引用的新数组。
  • 因为没有发生深拷贝,只有数组内容的拷贝。所以数组中的对象是相同的。
  • 这里还有什么array?应该是original

标签: javascript arrays operator-keyword spread-syntax


【解决方案1】:

这个问题的答案完全取决于copy 的意思。因为副本可以是浅的、深的,以及介于两者之间的一切。如果您只是想用对象的 shallow 克隆创建一个新数组,您可以使用 map 和 spread。例如:

const copy = original.map(item => ({ ...item }))

【讨论】:

  • 虽然此答案提供了一种获取数组中对象的“深层”副本(尽管只有一层深)的方法,但我认为这不是 OP 所要求的。他们在问“为什么我说 copy[i] = "foo" 不会改变原始数组,但如果他们说 copy[i].id = "foo"确实会改变原始数组
  • 如果您阅读他们最近的评论,他们会说,“是否有另一种方法可以复制数组和其中的对象,所以我可以只更改对象内部的键值,而不更改原始数组? ',而且我认为这仍然很肤浅。深度通常是指完整的深度。
  • 感谢 Matt Way,它对我帮助很大,现在它按我想要的方式工作了。
  • @MattWay 啊,没有看到他们最近的评论——我没有刷新。很高兴知道这可以满足 OP 的需要。
  • 你可以参考这个博客来了解rest / spread operator - tejassavaliya.medium.com/…
猜你喜欢
  • 1970-01-01
  • 2021-12-07
  • 1970-01-01
  • 2018-12-21
  • 2017-02-21
  • 1970-01-01
  • 2022-01-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多