Javascript函数不修改数组(引用?)

Javascript function not modifying array (reference?)

本文关键字:引用 数组 函数 修改 Javascript      更新时间:2023-09-26

如果JavaScript传递一个函数参数作为原始对象的引用,为什么我不能用这个简单的函数修改原始数组?

var array1 = ["one"];
function change(array) {
   var array2 = ["222"];
   array = array2;
}
change(array1);
console.log(array1); // this prints ["one"] instead of ["222"]

为什么有时对象似乎作为引用传递,而在这种情况下它是作为副本传递的?

为什么有时对象似乎作为引用传递,在这种情况下它是作为副本传递的?

它不是作为数组的副本传递,而是作为数组引用的副本传递。仍然只有一个数组,您可以使用该引用在函数中更改数组:

var array1 = ["one"];
function change(array) {
   array[0] = "222";
}
change(array1);
console.log(array1); // this prints ["222"]

你不能做的是用函数中的另一个数组替换数组。如果你给参数赋一个新的数组,那么它将指向新的数组,但是变量array1仍然没有改变,并且指向原来的数组。

因为参数arrayarray1不一样。它们是独立的变量。注意,变量是按值传递的,对于对象,它传递的是按值引用的副本。所以你需要这样做:

var array1 = ["one"];
array1 = change(array1);
function change(array) {
   var array2 = ["222"];
   array = array2;
   return array;  
}
console.log(array1);

你看到你所看到的是因为javascript中的所有对象,数组都被认为是对象,是通过引用传递的。初始化array2时,它会在内存中为该数组创建一个新的位置,一个新的引用。然后在change函数中,参数array是对array1的引用,但是当您将array设置为array2时,该变量的引用已更改为内存中的新位置,即array2所在的位置。

小提琴:http://jsfiddle.net/31s3LLjL/1/

var array1 = ["one"];
var array2 = ["one"];
var array3 = ["one"];
function change(array) {
   var array2 = ["222"];
   array = array2;
}
function change2(array) {
   array[0] = ["222"];
}
function change3(array) {
   var array2 = array;
   array2[0] = ["222"];
}
change(array1);
change2(array2);
change3(array3);
console.log(array1); // prints one
console.log(array2); // prints 222
console.log(array3); // prints 222

在第一个change函数中,初始化了一个新的数组(object)。在其他两个更改函数中,我们只处理对内存中单个位置的相同引用。

JavaScript内存存储的工作方式是使用执行上下文堆栈。每个执行上下文都有一个词法环境和一个变量环境。

词法环境是来自所有父执行上下文的变量集,例如,因此保存在全局上下文中的变量将始终可用。

变量环境是在当前执行上下文中声明的变量集。这就是你在你的例子中要改变的,变量环境变量。

function change(array) {
    var array2 = ["222"];
    array = array2;
}

以"array"保存在"可变环境"中为例。然后,array2 也是保存在变量环境中。如您所见,这里的词法环境根本没有改变。因此,一旦在函数中执行完成,控制返回,这个执行上下文就失去了作用域,并且有资格进行垃圾收集,因为它与任何词法环境都没有联系。

这就是为什么你使用的进程没有替换你传入的数组。您只是在局部作用域中替换了一个值。

你仍然可以修改传入的数组,它会改变数组本身,但如果你给该变量赋值,那么它将不再改变数组。

问题是您确实有一个引用调用,但随后更改了函数内部的引用本身,而不是引用的值。

你要做的是:

var array1 = ["one"];
function change(array) {
   var value = "222";
   array[0] = value;
}
change(array1);
console.log(array1); // this prints ["222"]

更通用的方法是在函数中使用一个新的array2,并将该数组返回(!)给调用者。这当然不是对数组进行更改,而是在调用这样的函数时,只需将返回值赋给原始数组,就可以实现相同的效果。