【问题标题】:Why changing array variables item affects the array it has been inserted to in Javascript? [duplicate]为什么更改数组变量 item 会影响它在 Javascript 中插入的数组? [复制]
【发布时间】:2014-10-01 16:03:32
【问题描述】:

这里有一些代码:

var a = [1,2,3];
var b = [5,4];
var c = 6;
a.push(b);
console.log(a);
b[0] = 1;
console.log(a);
console.log(b);
a.push(c);
console.log(a);
c = 7;
console.log(a);

这是控制台中的结果:

[ 1, 2, 3, [ 5, 4 ] ]
[ 1, 2, 3, [ 1, 4 ] ]
[ 1, 4 ]
[ 1, 2, 3, [ 1, 4 ], 6 ]
[ 1, 2, 3, [ 1, 4 ], 6 ]

谁能告诉我为什么在将 b 数组的第一项推送到 a 数组后更改它也会影响这里的 a 数组?例如,当我更改推送到数组的 c 变量的值时,它不会影响 a 数组,这也是我希望 b 发生的情况。

【问题讨论】:

  • 为了衡量您目前的理解,您希望b = [5,4]; c = b; c[0] = 1; console.log(b); 的表现如何?
  • console.log(b) 应该是 [5,4] 但我猜它会是 [1,4]。但这就是我要问的,为什么会这样?
  • 当然;我只是想确保您的困惑与 push 无关,而是更广泛地适用于数组引用。

标签: javascript arrays variables console


【解决方案1】:

javascript 中的对象(如数组)作为引用传递。所以,当你这样做时:

a.push(b)

您正在将b 的引用推入数组a。如果您稍后更改b,则只有一个b,因此它会在所有引用它的地方发生变化,包括在数组中。

另一种说法是a.push(b) 不会复制b。推入数组的内容只是指向与您一直相同的b,因此如果您更改b,数组中的引用仅指向b,因此通过数组查看值也会看到变化。


如果您确实想要将副本(不受原始更改影响)推送到数组中,您可以使用 .slice() 进行显式副本。

var a = [1,2,3];
var b = [5,4];
var c = 6;
a.push(b.slice());   // push a shallow copy of b

这是学习 javascript 时要掌握的相当基本的东西。当您在 javascript 中传递或分配对象时(数组是一种类型的对象),不会制作副本。相反,您最终会得到不止一部分代码都指向完全相同的对象。这显然是一个可以利用的特性,但这意味着当你想要一个与原作没有联系的独立副本时,你必须明确地制作一个副本。

与此相反,Boolean 或 Number 等原语被分配或作为副本传递。

【讨论】:

猜你喜欢
  • 2011-09-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多