Javascript函数不修改数组(参考?)

Javascript函数不修改数组(参考?),javascript,Javascript,如果JavaScript将函数参数作为原始对象的引用传递,为什么我不能用这个简单的函数修改原始数组 var array1 = ["one"]; function change(array) { var array2 = ["222"]; array = array2; } change(array1); console.log(array1); // this prints ["one"] instead of ["222"] 为什么有时对象似乎是作为引用传递的,而在这种情况

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

var array1 = ["one"];

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

change(array1);

console.log(array1); // this prints ["one"] instead of ["222"]

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

因为参数
array
array1
不同。它们是独立的变量。注意,变量是按值传递的,对于对象,它是按值传递引用的副本。因此,您需要:

var array1 = ["one"];

array1 = change(array1);

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

console.log(array1);
为什么有时对象似乎作为引用传递,在这种情况下 它作为副本传递

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

var array1 = ["one"];

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

change(array1);

console.log(array1); // this prints ["222"]

您不能做的是在函数中用不同的数组替换数组。如果为参数指定一个新数组,那么它将指向新数组,但变量
array1
仍保持不变,并指向原始数组。

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

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

变量环境是在当前执行上下文中声明的一组变量。这就是您在示例中所更改的变量环境变量

function change(array) {
    var array2 = ["222"];
    array = array2;
}
在本例中,
array
保存在变量环境中。然后,
array2
也保存在变量环境中。如您所见,这里的词汇环境根本没有改变。因此,一旦函数中的执行完成,并且控件返回,该执行上下文将失去作用域,并且可以进行垃圾收集,因为它与任何词法环境都没有关系

这就是为什么使用的进程没有替换传入的数组。您只是替换了本地范围中的一个值


您仍然可以修改传入的数组,它将更改数组本身,但如果您分配给该变量,那么它将不再更改数组。

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

小提琴:


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

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

您打算做的是:

var array1 = ["one"];

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

change(array1);

console.log(array1); // this prints ["222"]

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

只是该值可能是对对象的引用。这意味着
array1
array
是完全独立的副本,最初引用同一对象。我建议OP在他们的情况下这样做,因为他们不需要
array=array
赋值,请注意,如果OP想要对包含多个元素的数组进行多次修改,那么它的可伸缩性就没有那么高。“您仍然可以修改传入的数组,它将更改数组本身,但是如果您指定该变量,那么它将不再更改数组”,回答得很好,谢谢!
var array1 = ["one"];

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

change(array1);

console.log(array1); // this prints ["222"]