2012-07-31 71 views
4

我已經開始在我的一個項目中使用模塊模式。據我所知,它是這樣的:使用JavaScript模塊模式時應該在哪裏放置私有方法?

var obj = (function(foo){ 
    //Some initialization logic up here. 

    //Private methods 
    var privateBazz = function(){ 
     return "I'm known only to this closure!"; 
    }(); 

    //Public methods 
    return { 
     publicFoo: foo, 
     publicBar: function(){ 
      return foo + privateBazz; 
     } 
    } 
})(); 

這看起來在紙面上相當不錯的,在實踐中,似乎工作得相當好。頂部的初始化邏輯非常直觀,然後是私有方法,然後是公共的。

雖然我遇到過一個問題。我應該如何從return語句的範圍之外和obj的函數聲明的範圍內調用publicFoo或publicBar?

我目前的解決辦法是做這樣的事情:

var obj = (function(foo){ 
    //Private methods declared early for use. 
    var privateBazz = function(){ 
     return "I'm known only to this closure!"; 
    }(); 

    var privateBar = function(){ 
     return foo + privateBazz; 
    }; 

    //Some initialization logic up here. 
    var dependentOnBar = privateBar(); 

    //Public methods 
    return { 
     publicFoo: foo, 
     publicBar: privateBar 
    } 
})(); 

這工作,但突然我的私有變量的聲明都放在我的上述對象的私有財產申報。如果我試圖保持私有函數聲明與第一次調用它們的代碼接近,那麼問題會變得更加嚴重,所以我剛剛在頂部聲明瞭所有我需要的私有函數,然後再初始化屬性。再說一遍,這是有效的,但我習慣於讓代碼儘可能接近執行點。所以,在頂層聲明私有函數塊對我來說真的很尷尬。有沒有其他人有這種感覺,或者這只是我需要克服JavaScript的東西?當我看到這種情況發生時,我應該採取哪些措施?

+1

這就是它的工作原理。這並不罕見。只需用'var'聲明所有內容,並只返回公共變量。 – elclanrs 2012-07-31 04:00:52

+1

您可能已經知道它了,但爲了以防萬一,在這裏您可以獲得有關javascript設計模式的很好的資源http://addyosmani.com/resources/essentialjsdesignpatterns/book/ 它解釋了模塊模式和派生類等等。 – davids 2012-07-31 06:56:24

回答

1

這聽起來像你可以通過簡單地不使用對象符號來返回模塊來解決這個問題,而是初始化它並在你去時建立它。這會去是這樣的:

var obj = (function(foo){ 
    var self = {}; 
    //Some initialization logic up here. 

    //Private properties 
    var foo = "only accessible within this scope"; 

    //Private methods 
    var privateBazz = function(){ 
     return "I'm known only to this closure!"; 
    }(); 

    //Public Properties 
    self.publicFoo = foo; 

    //Public Methods 
    self.publicBar = function(){ 
     return foo + privateBazz; 
    }; 

    return self; 
})(); 
0

如果您效仿CommonJS Modules,則可以將屬性分配給exports對象,並通過合格名稱或非限定名稱從IIFE範圍內的其他位置訪問它們。

(function (exports, undefined) { 
    var priv1 = 42; 
    exports.pubOne = function() {}; 
    var localAlias = function() {}; 
    localAlias(42); 
    exports.pubTwo = localAlias; 
})(window.App); 

在這個例子中,Window.App可能是該模塊的命名空間我的全局對象,但你可以在一個空對象,或者一些深嵌套命名傳遞一樣容易。

1

這裏是我的解決辦法:如果你的回報是「私有」方法之前聲明的一切,讓公衆那些你想,那麼你可以打電話給你的私人公衆中反之亦然(在你的第一個樣本中,你的私人不能打電話給公衆,因爲他們沒有在那個時候宣佈)

var obj = (function() { 
    // All functions now have direct access to each other 
    var privateFunc = function() { 
     return "private "+publicFunc1(); 
    }; 

    var publicFunc1 = function() { 
     return "public 1 "; 
    }; 

    var publicFunc2 = function() { 
     return "public 2 "+publicFunc1(); 
    }; 


    var publicFunc3 = function() { 
     return "public 3 "+privateFunc(); 
    }; 

    // Return the object that is assigned to Module 
    return { 
     publicFunc1: publicFunc1, 
     publicFunc3: publicFunc3, 
     publicFunc2: publicFunc2 
    }; 
}()); 

alert(obj.publicFunc3()); 
相關問題