情景1:
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr = [];
}
doStuff(myArray);
console.log(myArray); // [2,3,4,5]
情景2:
var myArray = [2, 3, 4, 5];
function doStuff(arr) {
arr.pop();
}
doStuff(myArray);
console.log(myArray); // [2,3,4]
为什么方案1 不更新全局声明的数组,但方案2 呢?
答案 0 :(得分:2)
在第一个例子中:
您正在更改变量arr
,它仅仅是对数组[2, 3, 4, 5]
的引用,因此它不会保留对[2, 3, 4, 5]
的引用,而是保存对另一个数组的引用[]
。
在var myArray = [2, 3, 4, 5];
行:
myArray -----------------------------------> [2, 3, 4, 5]
然后在doStuff(myArray);
行:
myArray -----------------------------------> [2, 3, 4, 5]
↑
arr ----------------------------------------------/
然后在arr = [];
行:
myArray -----------------------------------> [2, 3, 4, 5]
arr ---------------------------------------> []
=> 因此,在致电doStuff
后, myArray
仍为[2, 3, 4, 5]
在第二个例子中:
您正在使用[2, 3, 4, 5]
中存储的arr
引用来调用其上的函数pop
来修改它。
在var myArray = [2, 3, 4, 5];
行:
myArray -----------------------------------> [2, 3, 4, 5]
然后在doStuff(myArray);
行:
myArray -----------------------------------> [2, 3, 4, 5]
↑
arr ----------------------------------------------/
然后在arr.pop();
行:
myArray -----------------------------------> [2, 3, 4, 5].pop()
↑
arr.pop() ----------------------------------------/
将数组改为:
myArray -----------------------------------> [2, 3, 4]
↑
arr ----------------------------------------------/
=> 因此,在致电doStuff
后, myArray
现在为[2, 3, 4]
答案 1 :(得分:0)
在第一种情况下,在第二种情况下实际修改数组时,您正在进行新的内存分配。
因此,在第一种情况下,该值不会被修改。
例如:
var myArrayOne = [2, 3, 4, 5];
function doStuff(arr) {
arr = [7,8,9]; //assigining a whole new object to the copy
}
doStuff(myArrayOne);
console.log(myArrayOne); // [2,3,4,5]
// Scenario 2
var myArrayTwo = [2, 3, 4, 5];
function doStuff(arr) {
arr.pop(); //modifying the internals of the arr object
}
doStuff(myArrayTwo);
console.log(myArrayTwo); // [2,3,4]
答案 2 :(得分:0)
在第一个函数中,您只需重新分配函数的参数。这对传递的数据没有影响。
在第二种情况下,您实际上是通过调用pop
来改变传递的数组。
以这种方式思考:在
中var a = 1
a = 2
1
是否以任何方式被修改?不,指向它的引用a
刚刚改变了。
答案 3 :(得分:0)
arr
是对数组的引用,它存在于内存中(你不知道在哪里,你不在乎)。当您说arr = []
时,您在内存中的某个位置创建了一个新数组,并更改arr
以引用该新数组。旧数组仍然存在于内存中。如果没有任何东西引用旧数组,那么它最终会被垃圾收集,但在这种情况下它仍然被myArray引用,所以它保持不变。
arr.pop()正在修改数组,而不是更改引用。