2015-05-30 32 views
1

我試圖瞭解如何公共屬性(顯示)模塊模式工作。通過Carl Danley "The Revealing Module Pattern"指出的優點是:(顯示)模塊模式,公共變量和返回語句

明確定義的公共方法和變量,導致增加可讀性

讓我們來看看這個代碼(fiddle):

var a = function() { 
    var _private = null; 
    var _public = null; 
    function init() { 
     _private = 'private'; 
     _public = 'public'; 
    } 
    function getPrivate() { 
     return _private; 
    } 
    return { 
     _public : _public, 
     init : init, 
     getPrivate : getPrivate, 
    } 
}(); 

a.init(); 
console.log(a._public); // null 
console.log(a.getPrivate()); // "private" 

它當致電a._public時返回null。我現在可以操縱公共財產,如a._public = 'public';。但我無法從我的對象內改變它。或者至少這些更改沒有通過。我有點期待它是"public",因爲它已被init-方法更新過。

這實際上是否意味着,我不能有任何方法,處理公衆屬性?然後公衆這種模式的屬性沒有什麼意義,對吧?我也試過這個沒有運氣(fiddle):

return { 
    _pubic : _public, 
    init2 : function() { 
     _public = 'public'; 
    } 
} 

最後,但並非最不重要,我有一個關於整個return陳述的問題。爲什麼不可能僅僅使用return this;來公開所有內容?由於this應該是自調函數的上下文,它不應該只是返回eveyrthing嗎?爲什麼我必須創建另一個對象,返回?在fiddle中,它返回window對象。

回答

3

這實際上是否意味着,我不能有任何方法,處理公共屬性?

不,這意味着你不能有公共變量var _public是一個變量,它不能從外部訪問,並且當您修改私有變量時,這不會反映在您的公共._public屬性中。

如果你想使事情公開,使用性質:

var a = function() { 
    var _private = null; 
    function init() { 
     _private = 'private'; 
     this._public = 'public'; 
    } 
    function getPrivate() { 
     return _private; 
    } 
    return { 
     _public : null, 
     init : init, 
     getPrivate : getPrivate, 
    } 
}(); 

我可以操縱公共財產,像a._public = '公共' ;.但我無法從我的對象內改變它。

您可以在對象的方法中使用this,如上所示。或者,您使用a來引用該對象,或者甚至可能存儲您返回的對象的本地引用。有關差異,請參閱here

,或者至少這些更改將不會通過

是過去了,因爲變量是不同性質(不同於像Java其他一些語言,並有例外全球的)。當您在對象文本中導出public: _public時,它將只取得_public變量中的當前值,並使用它創建對象的屬性。沒有對變量的持續引用,並且對其中一個的更改沒有反映在另一箇中。

爲什麼不可能僅僅使用return this;來公開所有內容?因爲這應該是自我調用函數的上下文,它不應該只是返回它的eveyrthing嗎?

變量是JavaScript中的範圍的一部分。 (除全球範圍外)這些範圍不是該語言可訪問的對象。

this keyword不引用此函數的作用域,而是引用該調用提供的上下文。這可以是方法調用中的基礎引用,構造函數調用中的新實例,也可以是像您的基本函數調用(或鬆散模式下的全局對象)中的任何內容。

+0

非常感謝您非常簡短的和有益的解釋。 – lampshade

+1

@TJCrowder:感謝您的信任:-)其實我在發佈這個存根後就去吃了午飯,看到您已經回答了......不幸的是,您刪除了您的答案,其內容甚至沒有保存在歷史記錄中: -/ – Bergi

+0

是的,我也看到了他的回答,也有一些很好的見解。但突然它消失了。 – lampshade

2

在您的模塊定義中,_public是通過值複製的,因爲在javascript中,只有對象通過引用分配。之後,它無法鏈接到當地的_public變量。因此,只有當您將對象中的_public「裝箱」,才能通過引用複製,或者引用模塊中的對象屬性,只有一個局部變量引用:

var a = function() { 
    var module = { 
     _public: null 
    }; 

    // use module._public here 

    return module; 
}(); 

a._public = "foo"; 
+0

看起來像一個很酷的把戲,把*東西放入對象中。謝謝。 – lampshade

0

您可以使用這種結構用於創建新類

function a(){ 
    var _private = null; 
    this.public = null; 
    this.getPrivate = function(){ 
     return _private; 
    }; 

    function init(){ 
     _private = "private"; 
     this.public = "public"; 
    } 

    init.apply(this, arguments); 
} 

//static function 
a.create = function(){ 
    return new a(); 
}; 

//using 
var b = new a(); 
//or 
var b = a.create();