Compare an object created by using an object literal to one created by the Revealing Module Pattern.
Here is one created as an object literal.
function makeGreeter(name){
return {
getName: function(){ return name;},
sayHello: function(){console.log("Hello, " + this.getName());}
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, George"
When you override the public method getName
on the returned object, the sayHello
method which depends on getName
picks up the change. This is because in the Object Literal style, references to public functions are made via this
, the returned object.
However, when you use the Revealing Module Pattern,
function makeGreeter(name){
var getName = function(){ return name;},
sayHello = function(){console.log("Hello, " + getName());};
return {
getName: getName,
sayHello: sayHello
}
}
var greeter = makeGreeter("Danny");
greeter.sayHello; // "Hello, Danny"
greeter.getName = function(){ return "George";}
greeter.sayHello(); // "Hello, Danny"
The RMP greeter will not pick up the override to the public getName
method. This is because when RMP functions reference other functions (both public and private), they refer to the private closure copy rather than to the public function attached to the returned object.
It is for this reason I regard the Revealing Module Pattern as an anti-pattern.
myRevealingModule.increment = newFunction;
doesn't change the inner workings of the module.myRevealingModule.start
will still call the internal, private increment function. This can be good or bad, depending on the context. – Thrill