对象 push()ed 到 Array 中



我希望了解将对象推送到数组中的以下行为。

(1(我创建一个对象,创建对象的属性,然后将其推送到数组中。

var array = [];
var obj = {};
obj.x = 1;
array.push(obj); 
console.log(array); //Output [{x: 1}]

考虑以下两种选择:

(2a(:我更改了对象的属性,因此更改了数组中引用的对象:

obj.x = 2;
console.log(array); //Output [{x: 2}] ... it has been changed

(2b而不是 2a(我使对象引用引用一个新对象并创建属性,数组中引用的原始对象保持不变:

obj = {}; //Change reference to new object
obj.x = 2;
console.log(array); //Output [{x: 1}] ... it is unchanged

为什么会这样呢?

PS:我注意到这里讨论了这种区别(对象是在javascript中推送到数组中的深度还是浅层复制?(,但它没有得到令人满意的解释。

我不知道我糟糕的ASCII图表技能是否有帮助,但这里有一个尝试:

-----------------------------------------
(1)
-----------------------------------------
array = []
[ ]    'array'
^--------/
obj = {}
[ ]    'array'   { }     'obj'
^--------/       ^-------/
obj.x = 1
[ ]    'array'   {x: 1}    'obj'
^--------/        ^---------/
array.push(obj)
,-----------------v
[0: * ]    'array'   {x: 1}    'obj'
^------------/        ^---------/
-----------------------------------------
(2a)
-----------------------------------------
obj.x = 2
,-----------------v
[0: * ]    'array'   {x: 2}    'obj'
^------------/        ^---------/

-----------------------------------------
(2b)
-----------------------------------------
obj = {}
,-----------------v
[0: * ]    'array'   {x: 1}    'obj'    { }
^------------/                  `-------^ 

obj.x = 2
,-----------------v
[0: * ]    'array'   {x: 1}    'obj'    {x: 2}
^------------/                  `--------^ 

JavaScript 对象通过对象引用推送到数组中,也就是说,如果您将对象推送到数组中,然后操作该对象,数组的内容似乎也会发生变化,因为数组引用了相同的对象。

通过初始化或克隆创建新对象可以避免此问题,数组中有两个完全不同的对象。

可以这样想:当你对一个对象调用push时,对象本身不会进入数组,而对对象的引用(指针(会进入数组。像数字这样的基元类型会被复制,对象不会被复制

  1. 当你推送一个对象时,你添加了第一个对象的引用,所以这就是它更新为 2 的原因

  2. 您正在创建新对象并分配给 obj,更改该对象不会更改数组值,因为它指向不同的引用。

最新更新