2016-09-19 130 views
2

我想通過引用傳遞基元變量。通過refence傳遞基元變量javascript

var foo = 2; 
function inc (arg) { 
    arg++ 
} 
inc(foo) //won't increment foo 

上述不起作用,因爲在JavaScript中,基元(如數字)通過值傳遞,而對象通過引用傳遞。爲了通過引用傳遞原語,我們需要把它們作爲申報對象:

var foo = new Number(2) 
function inc (arg) { 
    arg++ 
} 
inc(foo) //increments foo 

這似乎是一個非常哈克解決方法,而且很可能傷害了執行速度。在其他OO語言中,我們可以將「指針」或「引用」傳遞給函數。 JS中有這樣的東西嗎?謝謝!

+0

你在問什麼? JavaScript中沒有對基元進行傳遞引用。 – Cristy

+0

真正的問題在於你應該閱讀關於JS如何工作的範圍。一個簡單的鏈接:http://www.w3schools.com/js/js_scope.asp – manuerumx

+0

更好的鏈接:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures – manuerumx

回答

3

您無法在Javascript中通過引用傳遞基元 - 而示例「解決方法」不起作用。這裏的原因:

var foo = new Number(2) // line 1 
function inc (arg) {  // line 2 
    arg++    // line 3 
} 

線1套foo與原始值的數字對象包裝2.

2行定義了其在功能範圍自身的存儲位置來保存副本的形式參數arg參數的值。

第3行增加存儲它的實際參數值(Number對象引用的副本) - 分配給arg而不是foo的內存中。如果在調用後檢查foo原始值仍然是2

在實際應用中,你可以通過引用與一個Foo屬性的對象被遞增:

var obj = {} 
obj.foo = 2 
function incFoo (obj) { 
    obj.foo++ 
} 
incFoo() // obj.foo now 3 

本質上沒有地址在ECMA腳本中可用於引用原始值的指針。

+1

對象幾乎是通過引用傳遞的。它更像是一個引用的副本。但是這只是一個相當小的細節 - 它只意味着如果你在函數中接受一個參數'obj','obj = null'不會清除實際的對象。除此之外 - 你是對的,特別是關於'新號碼'不是一個解決方法。 – vlaz

+0

'@vlaz完全同意但可能用不同的術語來思考。我很久以前打折了「所有參數都是按值傳遞的(複製操作),除了通過引用傳遞的對象」有利於「所有參數都是按值傳遞的,包括對象數據類型,因爲對象數據類型包含對對象的引用數據存儲在別處。「 ;-) – traktor53