[英]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"]
為什么有時對象似乎是作為引用傳遞的,在這種情況下,它是作為副本傳遞的?
因為參數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函數中,參數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函數中,我們初始化一個新的數組(對象)。 在其他兩個更改函數中,我們僅對內存中的單個位置使用相同的引用。
問題是您確實有一個按引用進行調用,但是隨后在函數內部更改了引用本身,而不是所引用的值。
您打算做的是這樣的:
var array1 = ["one"];
function change(array) {
var value = "222";
array[0] = value;
}
change(array1);
console.log(array1); // this prints ["222"]
一種更通用的方法是在函數內部使用新的array2並將該數組返回(!)給調用者。 當然,這並不是更改數組,而是在調用此類函數時,只需將返回值分配回原始數組,即可實現相同的目的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.