我刚注意到克隆和推送物品的奇怪之处。这是一个例子:
let a = { foo: [1,2] };
let b = Object.assign({}, a) // cloning object and getting new reference
a === b // gives false which is what I want
现在我在对象a上做push
:
a.foo.push(3)
现在a.foo
为[1,2,3]
,b.foo
也是[1,2,3]
但如果我这样做
a.foo = a.foo.concat(4)
a.foo
为[1,2,3,4]
,b.foo
为[1,2,3]
问题是:为什么?
答案 0 :(得分:3)
a.foo和b.foo指向相同的引用,但.concat()返回一个新数组,因此它们现在指向2个不同的数组引用
答案 1 :(得分:2)
Object.assign
执行的操作称为shallow cloning
或shallow copying
。如果源值是对Object的引用,则它仅复制该引用值。
检查docs here并阅读 Deep Clone警告。
这也是push
影响对象a
和b
的原因,因为它实际上是执行操作的相同数组。
Array.prototype.concat
方法返回 new 数组对象,您将其指定给a.foo(a.foo = a.foo.concat(4)
),因此两个foo引用现在将指向2个不同的数组对象
concat()
方法用于合并两个或多个数组。这种方法 不会更改现有数组,而是返回一个新数组。
答案 2 :(得分:1)
为什么?
Object.assign({}, a)
会对您的对象a
const foo = {bar: []}
const baz = Object.assign({}, foo)
console.log(foo.bar === baz.bar)
但是Array.prototype.concat
会创建新数组
const foo = []
const bar = foo.concat()
console.log(foo === bar)
答案 3 :(得分:1)
因为在您的情况下a.foo
和b.foo
引用相同的数组。因此,一方的更改会影响另一方, Array.prototype.concat
会返回一个新数组并且不会改变第一个数组,这就是为什么在第二次调用中得到不同的结果,而不是到 array.prototype.push
这将改变初始数组。
<强> Array.prototype.concat 强>:
concat()
方法用于合并两个或多个数组。此方法不会更改现有数组,而是返回一个新数组。
<强> array.prototype.push 强>:
push()
方法将一个或多个元素添加到数组的末尾,并返回数组的新长度。
您可能还需要阅读What is the most efficient way to deep clone an object in JavaScript?,因为Object.assign()
只会复制对现有对象的引用。
答案 4 :(得分:0)
在这里阅读
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
指定不做深度复制,所以a.foo和b.foo指向同一个数组,所以当你推送它时会被添加到同一个数组
但是当你做concat时它实际上返回了新数组,现在两个数组都是不同的