【问题标题】:Objects push()ed into Array对象 push() 到数组中
【发布时间】:2019-02-22 20:48:34
【问题描述】:

我希望了解将对象推入数组时的以下行为。

(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

为什么会这样?

P.S:我注意到这里讨论了这个区别 (Do objects pushed into an array in javascript deep or shallow copy?),但没有得到令人满意的解释。

【问题讨论】:

  • 因为它是参考,而不是副本
  • 您能否具体说明一下您所指的解释不满意的地方?
  • 你不是自己解释的吗? 2a 修改变量和数组引用的对象,2b 创建第二个对象并仅修改它。
  • 数组中仍然引用了第一个对象。该引用作为 obj 被推送到数组中。当 obj 引用一个新对象时,那个原始引用是什么?
  • 原始引用仍然引用原始对象。一个对象不需要有任何类型的“为它分配空间的变量”就可以存在。如果您来自低级语言:每个 对象只是一个指针。对象字面量{} 在堆上创建动态对象并返回对它的引用。

标签: javascript arrays reference


【解决方案1】:

我不知道我糟糕的 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}
   ^------------/                  `--------^ 

【讨论】:

  • 谢谢。我在视觉上思考。
  • 我的困惑源于认为数组中有一个_obj_reference,而不是0索引引用的对象。
  • 您放在数组中的 * 的性质是什么,它指向对象。它是一种参考吗?
  • @StevenRJClarke1985:是的,这可能是最好的思考方式。我只是想在图表中为箭头指向的东西。没有它看起来很尴尬。关键是数组的第一个元素(索引0)指向内存中的其他内容。
【解决方案2】:
  1. 当你推送一个对象时,你添加了第一个对象的引用,所以这就是它更新为 2 的原因

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

【讨论】:

    【解决方案3】:

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

    通过初始化或克隆来创建一个新对象绕过了这个问题,数组中有两个完全不同的对象。

    这样想:当你在一个对象上调用push 时,对象本身不会进入数组,对象的引用(指针)会。像数字这样的原始类型会被复制,而对象则不会。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-15
      • 2012-02-14
      • 1970-01-01
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多