2012-12-19 58 views
5
function modify(val, newVal) { 
    val = newVal; 
} 
constructorFunc = function() { 
    var _private = false; 

    return { 
     modifyPrivate: function(toVal) { 
      return modify(_private, toVal); // LINE REFERRED TO BELOW AS X 
     } 
    }; 
} 
var x = constructorFunc(); 
x.modifyPrivate(true); 
x.modifyPrivate(true); // _private still starts off as false, meaning it wasn't set to true 

我有一個問題是爲什麼我第二次調用x.modifyPrivate(true)爲什麼當行X運行時,傳入的_private的值仍然是'false'。模組模式中的私人成員,不可變嗎?

如果我稍微修改我的閉包知識,以便通過引用完成閉包,並且當您更改引用的值時,您不會鏈接原始引用指向的值,那麼我可以理解正在改變參考本身以指向一些新的價值...但是這整個事情是非常混亂的,我確定有人在那裏可以指出我的網絡圖解釋這一點。

我對知道如何編寫此代碼非常感興趣,因此_private實際上是爲後續調用modify()而修改的。

+4

參數按值傳遞在JS中。這意味着你的「修改」功能是毫無意義的。即使'val'指向一個對象,它的_local_ copy(= reference也是)的值將被重寫 - 而不是對象本身。 – raina77ow

+0

是的,謝謝,我不能相信我忘記了。閉包使用引用,函數調用使用值。對! – JayPrime2012

回答

3

JavaScript總是按值傳遞,因此無法將變量傳遞給函數,並且該函數會在您嘗試執行時爲其分配新值。

實際上根本不需要modify函數。只是這樣做:

constructorFunc = function() { 
    var _private = false; 

    return { 
     modifyPrivate: function(toVal) { 
      _private = toVal; 
      return this; 
     } 
    }; 
} 
var x = constructorFunc(); 
x.modifyPrivate(true); 

modifyPrivate訪問私有_private的方法,因爲它是在內部範圍定義。它按照raina77ow的建議返回this,因此如果您願意,您可以鏈接另一個方法調用x(例如,x.modifyPrivate(true).foo(),如果您像modifyPrivate那樣定義foo)。


現在,如果你真的需要修改從沒有訪問該範圍的外部函數值,你可以用你的私人價值的對象,傳遞對象。在這種情況下,傳遞的值將是對象的引用,因此修改其屬性將會起作用(請注意,您不能重新分配給對象,只需操作屬性):

function modify(valObj, newVal) { 
    valObj.val = newVal; 
    // return whatever is apropriate 
} 
constructorFunc = function() { 
    var _private = { 
     val : false 
    }; 

    return { 
     modifyPrivate: function(toVal) { 
      return modify(_private, toVal); 
     } 
    }; 
} 
var x = constructorFunc(); 
x.modifyPrivate(true); 
+1

我寧願在setters中返回'this'。 ) – raina77ow

+0

有道理;返回'toVal'是一個猜測,我不確定OP想要返回什麼(原始代碼返回'undefined')。 – bfavaretto

+0

謝謝,我得到你。實際上,修改函數是一個「設置或獲取」,取決於是否有值,如果值被更改,它會更新我的數據庫,並且它也緩存值,所以它並不總是從數據庫中獲取。我需要以「我怎樣才能避免將我的'setOrGetMethod'封裝在這裏作爲'修改'功能,如bfavaretto暗示的方式來提出這個問題?因爲將邏輯轉化爲匿名方法來獲得_private似乎是不必要的。想想辦法......我不得不將所有的_private變量包裝在一個對象中並傳遞該對象嗎? – JayPrime2012