因此,我了解到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);
答案 0 :(得分:6)
a
和b
并非互相引用-它们是对相同数组的引用。
执行a = [5,5]
时,将a
设置为完全新的数组,而b
仍引用旧的数组。
答案 1 :(得分:3)
将“变量”与“值”区分开来可能会有所帮助。
您示例中的 a
和b
是变量。
[1,2,3]
,4
和[5,5]
是值。
多个变量可以引用相同的值。如果该值发生更改(变异),则引用该值的所有变量将返回更改后的值。下面的示例将a
和b
的引用设置为相同的值,然后通过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]
但是,您可以通过将变量“分配”为新值来更改变量所引用的值。这不会更改(更改)值本身,也不会更改碰巧引用相同值的任何其他变量的引用。下面的示例将a
和b
的引用设置为相同的值,然后将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)
让我们看一下计算机的内存¹。首先,创建两个变量a
和b
。这些基本上是内存位置,并填充了一个值:
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的概念是从其他语言衍生而来的,这就是为什么低级思考通常会有所帮助的原因。
²没有诸如特定存储位置的名称之类的东西,为了清楚起见,我只是添加了这个名称。