JavaScript Module Pattern - What about using "return this"?

Rob Gibbons picture Rob Gibbons · Apr 26, 2010 · Viewed 12.3k times · Source

After doing some reading about the Module Pattern, I've seen a few ways of returning the properties which you want to be public.

One of the most common ways is to declare your public properties and methods right inside of the "return" statement, apart from your private properties and methods. A similar way (the "Revealing" pattern) is to provide simply references to the properties and methods which you want to be public. Lastly, a third technique I saw was to create a new object inside your module function, to which you assign your new properties before returning said object. This was an interesting idea, but requires the creation of a new object.

So I was thinking, why not just use this.propertyName to assign your public properties and methods, and finally use return this at the end? This way seems much simpler to me, as you can create private properties and methods with the usual var or function syntax, or use the this.propertyName syntax to declare your public methods.

Here's the method I'm suggesting:

(function() {

var privateMethod = function () {
    alert('This is a private method.');
}

this.publicMethod = function () {
    alert('This is a public method.');
}

return this;

})();

Are there any pros/cons to using the method above? What about the others?

Answer

viam0Zah picture viam0Zah · Apr 26, 2010

Your function has no object context, so this references to the global window object in this case. Every property you assign to this automatically pollutes the global namespace.

(function() {
    console.log(this == window); // true

    this.publicMethod = function () {
        alert('This is a public method.');
    }

})();

console.log(publicMethod); // function()

You can explicitly pass it an object to tell which context to use.

var MYAPP = {};

(function() {
    // 'this' will now refer to 'MYAPP'
    this.publicMethod = function () {
        alert('This is a public method.');
    }
}).call(MYAPP);

console.log(publicMethod); // undefined
console.log(MYAPP.publichMethod); // function()

Which you can write in somewhat other style:

var MYAPP = (function(my) {
    var my;
    ⋮
    return my;
})(MYAPP);

And we arrived to an already discussed pattern. For further details, see Dustin's article on Scoping anonymous functions.