2017-06-19 39 views
0

修改的功能的陣列其所傳遞

function nextInLine(arr, item) { 
 
    arr.push(item); 
 
    var removedItem = arr.shift(); 
 
    return removedItem; 
 
} 
 

 
// Test Setup 
 
var testArr = [1,2,3,4,5]; 
 

 
// Display Code 
 
console.log("Before: " + JSON.stringify(testArr)); 
 
console.log(nextInLine(testArr, 6)); 
 
console.log("After: " + JSON.stringify(testArr)); //*THIS LINE HERE*

在上面的代碼段,這是爲什麼認爲第三console.log線打印[2,3,4,5,6] ..按我的邏輯,當testArr傳遞到nextInLine函數,只有testArr的副本作爲參數傳遞。因此,第3條console.log行必須按原樣打印[1,2,3,4,5],不作任何更改!

任何幫助表示讚賞。謝謝。

+3

是什麼讓你認爲數組在被調用時被複制?這不是JavaScript的工作原理。 –

+2

[JavaScript是傳遞引​​用還是傳值語言?]的可能重複(https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass按值語言) – david

回答

1

使用Javascript

對象通過引用傳遞。數組只是一個對象。

所以當你路過陣列的功能,它實際上是傳遞一個引用然後把它修改

var a = [1,2,3,4,5]; 

var b = a; 

b[0] = 2; 

console.log(a); //outputs [2,2,3,4,5] 

編輯b實際上將編輯更新一個爲b是指向外陣列到存儲位置的一個

+0

這只是清除了事情! 謝謝。 – iamrkcheers

0

當您發送數組或對象時,JavaScript通過引用傳遞。參考:Is JavaScript a pass-by-reference or pass-by-value language?

要解決您的問題,nextInLine(testArr.slice(), 6)會創建一個數組的副本。

+0

在一般的編程術語中,「通過引用傳遞」意味着函數可以修改外部變量的值,這在JS中是不可能的。所有的JS參數都是通過值傳遞的,但是對於對象/數組,這個值是一個引用。 – nnnnnn

+0

這就是在OP的情況下發生的情況 – gauravmuk

+0

「Pass by reference」不是發生了什麼事情,因爲如果函數說'arr = null'根本不會影響'testArray'變量。但'arr'參數確實接收到'testArray'引用的同一個對象的引用,所以它可以改變*那個特定的對象。 – nnnnnn

0

在JavaScript中,如果你這樣做:var x = y其中y對象,X現在是一個指針爲y。所以,如果你這樣做:x.foo = 5,y也將有foo等於5。但是,如果您這樣做:x = 10,它不會影響y,因爲您正在分配新值x

另請注意,數組是一個對象在Javascript中,以便解釋您的情況。更多示例(與您的情況類似):

var y = []; 
var x = y; 
x.push(5); 
console.log(x); [5] 
console.log(y); [5] 
x = 10; 
console.log(x); 10 
console.log(y); [5] 

有關更多詳細信息,請檢查this SO answer

0

正如大家在這裏已經提到的所有對象在JavaScript(包括數組)通過函數的引用傳遞。因此,當您將testArr傳遞給nextInLine函數時,函數將使用語句arr.push(item);對原始數組進行變異。

但是,如果您想防止這種情況發生,您可以將testArr的副本/克隆傳遞給函數。 使數組的副本最簡單的方法是這樣的:

var testArr = [1,2,3,4,5]; 
var copyOfTestArr = testArr.slice(0); 

另外,也可以使nextInLine功能不可變的沒有突變的原始參數如下:,

function nextInLine(arr, item) { 
    var removedItem = arr.concat([item]).shift(); 

    return removedItem; 
} 

// Test Setup 
var testArr = [1,2,3,4,5]; 

// Display Code 
console.log("Before: " + JSON.stringify(testArr)); 
console.log(nextInLine(testArr, 6)); 
console.log("After: " + JSON.stringify(testArr)); //*THIS LINE HERE* 

現在,如果你測試這個新功能,你應該得到預期的輸出。