将对象推入javascript深拷贝还是浅拷贝中的数组?

Posted

技术标签:

【中文标题】将对象推入javascript深拷贝还是浅拷贝中的数组?【英文标题】:Do objects pushed into an array in javascript deep or shallow copy? 【发布时间】:2012-01-29 11:03:23 【问题描述】:

相当不言自明的问题...当在 javascript 中的数组上使用 .push() 时,推入数组的对象是指针(浅)还是实际对象(深)不管输入。

【问题讨论】:

【参考方案1】:

这取决于你要推动什么。对象和数组作为指向原始对象的指针被推送。内置的原始类型(如数字或布尔值)作为副本推送。因此,由于对象不会以任何方式复制,因此它们没有深拷贝或浅拷贝。

这是一个显示它的工作 sn-p:

var array = [];
var x = 4;
let y = name: "test", type: "data", data: "2-27-2009";

// primitive value pushes a copy of the value 4
array.push(x);                // push value of 4
x = 5;                        // change x to 5
console.log(array[0]);        // array still contains 4 because it's a copy

// object reference pushes a reference
array.push(y);                // put object y reference into the array
y.name = "foo";               // change y.name property
console.log(array[1].name);   // logs changed value "foo" because it's a reference    

// object reference pushes a reference but object can still be referred to even though original variable is no longer within scope
if (true) 
    let z = name: "test", type: "data", data: "2-28-2019";
    array.push(z);


console.log(array[2].name);   // log shows value "test" since the pointer reference via the array is still within scope

【讨论】:

吹毛求疵:每个值都被推送作为一个值;在对象的情况下,这些值恰好是对象的“指针”。【参考方案2】:

jfriend00 在这里是正确的,但需要澄清一点:这并不意味着您不能更改变量指向的内容。也就是说,y 最初引用了您放入数组中的某个变量,但是您可以获取名为 y 的变量,将其与现在数组中的对象断开连接,然后连接 y(即 让它引用)完全不同的东西不改变现在只被数组引用的对象

http://jsfiddle.net/rufwork/5cNQr/6/

var array = [];
var x = 4;
var y = name: "test", type: "data", data: "2-27-2009";

// 1.) pushes a copy
array.push(x);
x = 5;
document.write(array[0] + "<br>");    // alerts 4 because it's a copy

// 2.) pushes a reference
array.push(y);
y.name = "foo";

// 3.) Disconnects y and points it at a new object
y = ; 
y.name = 'bar';
document.write(array[1].name + ' :: ' + y.name + "<br>");   
// alerts "foo :: bar" because y was a reference, but then 
// the reference was moved to a new object while the 
// reference in the array stayed the same (referencing the 
// original object)

// 4.) Uses y's original reference, stored in the array,
// to access the old object.
array[1].name = 'foobar';
document.write(array[1].name + "<br>");
// alerts "foobar" because you used the array to point to 
// the object that was initially in y.

【讨论】:

关于使用new“断开”对象引用的有趣点。 否决解释?如果你不让我知道它是什么,很难解决这个问题。 为什么要ping我?我很久以前就赞成这个并且确实喜欢你的回答。这是投票屏幕:i.imgur.com/AnDt98c.png 对不起@Travis - SO 的附带损害我没有其他方式与最近一两周来的匿名投票者交流。我没想到它来自你,尤其是。与您的积极评价。很抱歉给您带来了不幸的垃圾邮件,感谢您一直关注您的问题! 这实际上是我的一个误解。我的错。您的评论显示在我的通知中,我认为它是针对我的,因为我没有意识到作为 OP 所有 cmets 都显示为通知。

以上是关于将对象推入javascript深拷贝还是浅拷贝中的数组?的主要内容,如果未能解决你的问题,请参考以下文章

经典前端面试题: Object.assign 是浅拷贝还是深拷贝?实现深拷贝的方法有哪些?

JavaScript中的浅拷贝和深拷贝

JavaScript深拷贝和浅拷贝

Javascript中的深拷贝和浅拷贝

Java中的深拷贝(深复制)和浅拷贝(浅复制)

C++中,啥是深拷贝?啥是浅拷贝?