Javascript函数不修改数组(引用?)
Javascript function not modifying array (reference?)
如果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
仍然没有改变,并且指向原来的数组。
因为参数array
和array1
不一样。它们是独立的变量。注意,变量是按值传递的,对于对象,它传递的是按值引用的副本。所以你需要这样做:
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,并将该数组返回(!)给调用者。这当然不是对数组进行更改,而是在调用这样的函数时,只需将返回值赋给原始数组,就可以实现相同的效果。
- JavaScript变量引用数组时出现问题
- 在 Larawel 中存储引用数组
- 引用数组 JavaScript
- 调用变量以引用数组
- 使用_id引用数组对多个相应文档进行高效查询
- 出现错误:使用javascript引用数组的索引
- 如何在函数参数中引用数组
- 在jsView中引用数组元素
- 在javascript中引用数组的运行时间
- 基本引用数组中的对象
- 为什么当数组更新时,引用数组元素的n't是我的对象
- 从对象键获取引用数组的最快方法
- 在Moongoose (MongoDB)中通过嵌入引用数组查找文档
- AngularJS/JSON:通过值而不是索引来引用数组成员
- Javascript中的引用数组与值数组
- Javascript:使用变量引用数组,而不是复制它
- 使用eval来引用数组
- 如何通过侦听器引用数组中的当前dom元素来更改活动
- 在Javascript中引用数组的最后一个元素
- 如何查找引用数组的三个变量的重复项