5

我试图了解(显示)模块模式中的public` 属性是如何工作的。Carl Danley “ The Revealing Module Pattern指出的一个优点是:

显式定义的公共方法和变量,可提高可读性

让我们看一下这段代码(小提琴):

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"

null调用时返回a._public。我现在可以操纵该公共财产,例如a._public = 'public';. 但我不能从我的对象中改变它。或者至少这些更改没有通过。我有点期待它会"public"像之前通过 - 方法更新的那样init

这实际上是否意味着,我不能有任何方法来处理公共属性?那么这种模式下的公共属性就没有意义了,对吧?我也试过这个没有运气(小提琴):

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

return最后但并非最不重要的一点是,我对整个声明有疑问。为什么不能只使用return this;公开所有内容?应该是自this调用函数的上下文,它不应该只返回其中的所有内容吗?为什么我必须创建另一个返回的对象?在这个小提琴中,它返回window对象。

4

3 回答 3

8

这实际上是否意味着,我不能有任何方法来处理公共属性?

不,这意味着您不能拥有公共变量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 = 'public';。但我不能从我的对象中改变它。

您可以this在对象的方法中使用,如上所示。或者您使用a来引用对象,或者甚至可能存储对您返回的对象的本地引用。有关差异,请参见此处

或者至少这些更改没有通过

是的,因为变量与属性不同(与 Java 等其他一些语言不同,全局变量除外)。当您public: _public在对象文字中导出时,它仅从_public变量中获取当前值并使用它在对象上创建一个属性。没有对变量的持久引用,对一个变量的更改不会反映在另一个变量中。

为什么不能只使用return this;公开所有内容?由于这应该是自调用函数的上下文,它不应该只返回其中的所有内容吗?

变量是JavaScript范围的一部分。(全局范围除外)这些范围不是该语言可访问的对象。

this关键字不是指函数的这个范围,而是指调用提供的上下文。这可以是方法调用中的基本引用,构造函数调用中的新实例,或者像您这样的基本函数调用中的任何内容(或window松散模式下的全局对象)。

于 2015-05-30T11:19:57.107 回答
5

在您的模块定义中,_public是按值复制的,因为在 javascript 中,只有对象是通过引用分配的。之后,它与本地 _public 变量没有任何链接。因此,这仅在您将 _public “装箱”在一个对象中时才有效,因此它通过引用被复制,或者您在模块中也引用了该对象的属性,只有一个对局部变量的引用:

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

    // use module._public here 

    return module;
}();

a._public = "foo";
于 2015-05-30T11:22:43.580 回答
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();
于 2015-05-30T12:45:37.787 回答