簡體   English   中英

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"]

為什么有時對象似乎是作為引用傳遞的,在這種情況下,它是作為副本傳遞的?

因為參數arrayarray1 它們是單獨的變量。 請注意,變量是按值傳遞的,對於對象,它按值傳遞引用的副本 因此,您需要執行以下操作:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM