javascriptmodule-patternrevealing-module-pattern

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


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.


Solution

  • 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).