(揭示)模块模式,public 变量和 return-语句

(Revealing) Module Pattern, public variables and return-statement

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

Explicitly defined public methods and variables which lead to increased readability

让我们看一下这段代码(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时returns null。我现在可以像 a._public = 'public'; 一样操纵 public 属性。但我无法从我的对象中更改它。或者至少这些更改没有通过。我有点期待它是 "public" 因为它是由 init 之前的方法更新的。

这是否真的意味着我不能有任何方法来处理 public 属性?那么这个模式中的 public 属性就没什么意义了,对吧?我也没有运气就试过了(fiddle):

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

最后但同样重要的是,我对整个 return 声明有疑问。为什么不能仅使用 return this; 来使所有内容成为 public?由于 this 应该是自调用函数的上下文,它不应该只是 return everyrthing 在里面吗?为什么我必须创建另一个对象,即 returned?在此 fiddle 中,它 return 是 window 对象。

Does this actually mean, that I can't have any methods, that handle public properties?

不,这意味着你不能有public 变量var _public 是一个变量,它不能从外部访问,当你修改私有变量时,这不会反映在你的 public ._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,
    }
}();

I can manipulate that public property, like a._public = 'public';. But I can't change it from within my object.

您可以在对象的方法中使用this,如上所示。或者您使用 a 来引用该对象,或者甚至可能存储对您 return 的对象的本地引用。请参阅 here 以了解差异。

Or at least those changes aren't passed through

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

Why isn't it possible to just use return this; to make everything public? As this should be the context of the self-invoked function, shouldn't it just return eveyrthing in it?

变量是Java脚本中作用域的一部分。 (全局范围除外)这些范围不是语言可访问的对象。

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

在您的模块定义中,_public 是按值复制的,因为在 javascript 中,只有对象是按引用分配的 。之后,它对本地 _public 变量没有任何 link。因此,这只有在您 "box" 对象中的 _public 时才有效,因此它通过引用被复制,或者您也在模块中引用对象的 属性,只有一个对本地的引用变量:

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

    // use module._public here 

    return module;
}();

a._public = "foo";

您可以使用此构造来创建新的 class

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();