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

核能气质少年 提交于 2019-12-24 00:42:39

问题


I'm trying to understand how public` properties in the (Revealing) Module Pattern work. An advantage pointed out by Carl Danley "The Revealing Module Pattern" is:

Explicitly defined public methods and variables which lead to increased readability

Let's take a look at this code (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"

It returns null when calling a._public. I now can manipulate that public property, like a._public = 'public';. But I can't change it from within my object. Or at least those changes aren't passed through. I was kinda expecting it to be "public" as it was updated by the init-method before.

Does this actually mean, that I can't have any methods, that handle public properties? Then public properties in this pattern make little sense, right? I also tried this without luck (fiddle):

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

Last, but not least, I have a question regarding the whole return statement. 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? Why do I have to create another object, that is returned? In this fiddle it returns the window object.


回答1:


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

No, it means that you cannot have public variables. var _public is a variable, and it is not accessible from outside, and when you modify the private variable this will not be reflected in your public ._public property.

If you want to make things public, use properties:

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.

You can use this in the methods of your object, as shown above. Or you use a to reference the object, or possibly even store a local reference to the object you return. See here for the differences.

Or at least those changes aren't passed through

Yes, because variables are different from properties (unlike in some other languages like Java, and with exceptions for global ones). When you export public: _public in your object literal, it takes only the current value from the _public variable and creates a property on the object with it. There is no persistent reference to the variable, and changes to one are not reflected in the other.

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?

Variables are part of a scope in JavaScript. (Except for the global one) those scopes are not objects accessible to the language.

The this keyword does not refer to this scope of the function, but to the context that was provided by the call. That can be the base reference in a method call, the new instance in a constructor invocation, or just nothing in a basic function call like yours (or the global window object in loose mode).




回答2:


In your module definition, _public is copied by value, because in javascript, only objects are assigned by reference. After that it has no link to the local _public variable whatsoever. This would therefore only work if you either "box" the _public in an object, so it gets copied by reference, or you refer to the object's property within your module as well, having only one reference to the local variable:

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

    // use module._public here 

    return module;
}();

a._public = "foo";



回答3:


You can use this construction for creating new 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();


来源:https://stackoverflow.com/questions/30545445/revealing-module-pattern-public-variables-and-return-statement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!