2015-11-10 41 views
1

我試圖創建一個接受全局變量作爲參數並更改該全局變量的值的函數。這裏有一個簡單的例子,說明了什麼我想要做的事:Javascript:如何創建一個函數1.接受一個全局變量作爲參數2.改變該全局變量的值?

var number = 20; 
function setnew(num) { 
    num += 1; 
}; 

setnew(number); 
console.log(number) //-> 20 
        //I want this to return 21 

setnew函數被調用後,也number保持不變。有人可以解釋爲什麼number保持不變,並建議另一種方法來實現我的預期目標?

回答

1

由於Javascript不支持真正的引用傳遞,您可以在其中更改原始變量,因此無法直接執行所要求的操作。通常的解決方法是將全局包裝在一個對象中。

var myGlobal = { 
    counter: 0; 
}; 

function increment(obj, prop) { 
    ++obj[prop]; 
} 

increment(myGlobal, "counter"); 
increment(myGlobal, "counter"); 

console.log(myGlobal.counter); // 2 

或者,如果屬性名稱是已知的,你可以這樣做:

var myGlobal = { 
    counter: 0; 
}; 

function incrementCnt(obj) { 
    ++obj.counter; 
} 

incrementCnt(myGlobal); 
incrementCnt(myGlobal); 

console.log(myGlobal.counter); // 2 

這工作,因爲當你傳遞一個對象給一個函數,什麼是傳遞的是一個指向同一對象的指針(該對象不被複制)。因此,如果您修改該對象上的任何屬性,則只有該對象的一個​​副本,因此您要修改該對象的該副本的屬性,並且引用該對象的每個人都將看到屬性更改。

像數字和布爾值這樣的原始數據按值傳遞,它的工作方式與複製相同,因此原始數據不會受到該函數的影響。


有人能解釋爲什麼number保持不變,並建議另 的方式來實現我的預期目標?

將數字傳遞給函數時,數字的值被複制到作爲函數參數的新變量中。僅將該參數的值更改爲該函數會影響該參數 - 它根本沒有連接到原始變量。這是因爲在Javascript中,原語是通過值傳遞的,而不是通過引用。所以,沒有任何關於價值來自哪裏的參考。當你在函數中接收它時,它是一個獨立的新變量。


另一種可能的解決辦法是剛剛從你的函數返回修改後的值,並允許呼叫者分配該修改的值到任何他們想要的:

var counter = 0; 

function increment(val) { 
    return val + 10; 
} 

counter = increment(counter); 

console.log(counter); // 10 
0

如果你是一個傳遞對象而不是基元,你可以更新它。

例如:

var number = { value: 20 }; 
function setnew(num) { 
    num.value += 1; 
}; 

setnew(number); 
console.log(number.value) //-> 21 

基本上當你在一個對象傳遞,JavaScript是實際上只傳遞一個參考變量,而當傳遞的整數,它是要傳值的副本。

相關問題