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

发布于 2024-12-23 14:21:54 字数 89 浏览 3 评论 0原文

非常不言而喻的问题...当在 javascript 中的数组上使用 .push() 时,推入数组的对象是指针(浅)还是实际对象(深)无论类型如何

Pretty self evident question...When using .push() on an array in javascript, is the object pushed into the array a pointer (shallow) or the actual object (deep) regardless of type.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

儭儭莪哋寶赑 2024-12-30 14:21:54

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

这是一个显示它的工作片段:

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

It depends upon what you're pushing. Objects and arrays are pushed as a pointer to the original object . Built-in primitive types like numbers or booleans are pushed as a copy. So, since objects are not copied in any way, there's no deep or shallow copy for them.

Here's a working snippet that shows it:

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
漫漫岁月 2024-12-30 14:21:54

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

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.

jfriend00 is right on the mark here, but one small clarification: That doesn't mean you can't change what your variable is pointing to. That is, y initially references some variable that you put into the array, but you can then take the variable named y, disconnect it from the object that's in the array now, and connect y (ie, make it reference) something different entirely without changing the object that now is referenced only by the array.

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.
原来是傀儡 2024-12-30 14:21:54

JavaScript:在 2023 年创建对象的深层副本

不要在 JavaScript 中使用 Object.assign() 来复制或克隆对象!它会创建对象的浅表副本,并会将深层对象分配给副本中的引用指针!

您有两个选择

使用旧的、更可靠的 JSON 技巧:

const obj1 = JSON.parse(JSON.stringify(YourObject));

或者尝试新的 &改进的 structuralClone() 方法。 警告:这仅适用于自2022以来更新了常绿浏览器的用户!不支持 Internet ExplorerEdge Trident 浏览器!

const obj2 = structuredClone(YourObject);

JavaScript: Create a Deep Copy of an Object in 2023

Do NOT use Object.assign() in JavaScript to copy or clone objects! It creates a shallow copy of your object and will assign deep objects to reference pointers in your copy!

You have two choices.

Use the older, more reliable JSON trick:

const obj1 = JSON.parse(JSON.stringify(YourObject));

Or try the new & improved structuredClone() method. Warning: This only works for users who have updated their evergreen browsers since 2022! No Internet Explorer or Edge Trident browser support!!

const obj2 = structuredClone(YourObject);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文