数组可变性和变量参考方案尚不清楚

时间:2019-06-14 18:46:32

标签: javascript variables mutability

因此,我了解到JavaScript中的数组是可变的。

这意味着,如果我创建数组a和数组b = a,那么如果我修改数组a,则该修改在数组b中也是可见的。

但是,在以下情况下,我不明白为什么b丢失了对数组a的“引用”。

var a = [1,2,3];
var b = a;

console.log('a =', a);
console.log('b =', b);

a[0] = 4;
console.log('a =', a);
console.log('b =', b);

a = [5,5];
console.log('a =', a);
console.log('b =', b);

3 个答案:

答案 0 :(得分:6)

ab并非互相引用-它们是对相同数组的引用。

执行a = [5,5]时,将a设置为完全的数组,而b仍引用旧的数组。

答案 1 :(得分:3)

将“变量”与“值”区分开来可能会有所帮助。

您示例中的

ab是变量。

您示例中的

[1,2,3]4[5,5]是值。

多个变量可以引用相同的值。如果该值发生更改(变异),则引用该值的所有变量将返回更改后的值。下面的示例将ab的引用设置为相同的值,然后通过a的引用和b的引用对值进行更改。结果是两个变量仍引用更改后的值。

var a = [1,2,3]; // a references the value [1,2,3]
var b = a; // b references the value [1,2,3]
a[0] = 4; // [1,2,3] changed to [4,2,3]
b[1] = 5; // [1,2,3] changed to [4,5,3]
console.log(a); // [4,5,3]
console.log(b); // [4,5,3]

但是,您可以通过将变量“分配”为新值来更改变量所引用的值。这不会更改(更改)值本身,也不会更改碰巧引用相同值的任何其他变量的引用。下面的示例将ab的引用设置为相同的值,然后将a的引用更改为新的值。结果是变量现在引用了不同的值。

var a = [1,2,3]; // a references the value [1,2,3]
var b = a; // b references the value [1,2,3]
a = [5,5]; // a reference assigned to new value [5,5]
console.log(a); // [5,5]
console.log(b); // [1,2,3]

答案 2 :(得分:2)

让我们看一下计算机的内存¹。首先,创建两个变量ab。这些基本上是内存位置,并填充了一个值:

 location | name²      |  value
 -------------------------------------
  1       |  a         |  undefined
  2       |  b         |  undefined

现在a被初始化,并创建一个新的数组。但是,该数组不会直接存储在变量下,而是存储在a内的另一个位置,只是对该位置的引用:

  location | name²      |  value
  -------------------------------------
  1        |  a         |  ➡️ 3
  2        |  b         |  undefined
  3        |            |  [1, 2, 3]

现在b = a引用被复制时,您最终到达:

  location | name²      |  value
  -------------------------------------
  1        |  a         |  ➡️ 3
  2        |  b         |  ➡️ 3
  3        |            |  [1, 2, 3]

现在,当您执行a = [5,5]时,将创建另一个数组,并且a会引用该数组。 b虽未更改,但仍引用另一个数组。

  location | name²      |  value
  -------------------------------------
  1        |  a         |  ➡️ 4
  2        |  b         |  ➡️ 3
  3        |            |  [1, 2, 3]
  4        |            |  [5, 5]

或者,如果您执行b = {value: a}

  location | name²      |  value
  -------------------------------------
  1        |  a         |  ➡️ 4
  2        |  b         |  ➡️ 5
  3        |            |  [1, 2, 3] // waiting for GC
  4        |            |  [5, 5]
  5        |            | { value: ➡️4 }

¹是的,JavaScript是一种解释型语言,因此您不确定将它最终存储在内存中的方式,这取决于引擎。但是,JS的概念是从其他语言衍生而来的,这就是为什么低级思考通常会有所帮助的原因。

²没有诸如特定存储位置的名称之类的东西,为了清楚起见,我只是添加了这个名称。