Module 16: Unleash the Beast: Openly Revealing Your Feelings
Revealing Module Pattern
description
Transcript of Revealing Module Pattern
Revealing Module Pattern
But First… the Module Pattern• Established in 2003 by Richard Cornford• Made popular by Douglas Crockford• Based on IIFEs (Immediate Invoking Function Expression)
aka Self Executing Anonymous Function
var someModule = (function() { …})();
Immediate Invoking
Function Expression
The Build-Upfunction foo() { // Function Declaration …}
var foo = function() { // Function Expression (classy) …}
var foo = function() { // IIFE …}();
var foo =(function() { // IIFE also …})();
IIFEs are not Closuresvar person = (function() {
})(); // Immediately Invoked
var foo = function(x) { var y = 0; var bar = function bar() { return x; } return bar; // Closure};
IIFEs are not Closuresvar person = (function() {
})(); // Immediately Invoked
var foo = function(x) { var y = 0; var bar = function bar() { return x; } return bar; // Closure};
var something = foo(5); // something is a reference to the bar() function
IIFEs are not Closuresvar person = (function() {
})(); // Immediately Invoked
var foo = function(x) { var y = 0; var bar = function bar() { return x; } return bar; // Closure};
var something = foo(5); // something is a reference to the bar() function
alert(something()); // Alerts 5. This is because bar() is still “alive” within foo and remembers what foo’s X is
var someModule = (function() {
})();
So, back to the Module Pattern
var someModule = (function() { var x = 5;
})();
var someModule = (function() { var x = 5; var foo = function() { return x; }
})();
var someModule = (function() { var x = 5; var foo = function() { return x; } return {} // Return Object Literal (JSON)
})();
var someModule = (function() { var x = 5; var foo = function() { return x; } return {} // Return Object Literal (JSON)
})();
{my_num: 3, a: true, thing: ‘some string’}
key: value
var someModule = (function() { var x = 5; var foo = function() { return x; } return {} // Return Object Literal (JSON)
})();
{ my_num: 3, a: true, thing: ‘some string’}
var someModule = (function() { var x = 5; var foo = function() { return x; } return {} // Return Object Literal (JSON)
})();
{ my_num: 3, a: true, thing: ‘some string’, sub_json: {a: 1, b: 23}}
var someModule = (function() { var x = 5; var foo = function() { return x; } return {} // Return Object Literal (JSON)
})();
{ my_num: 3, a: true, thing: ‘some string’, some_function: function() { … }}
var someModule = (function() { var x = 5; var foo = function() { return x; } return {
}})();
var someModule = (function() { var x = 5; var foo = function() { return x; } return { bar: function() { return foo(); } }})();
var someModule = (function() { var x = 5; var foo = function() { return x; } return { bar: function() { return foo(); } }})();
alert(someModule.x); // Undefined
Private (ish)
var someModule = (function() { var x = 5; var foo = function() { return x; } return { bar: function() { return foo(); } }})();
alert(someModule.x); // Undefinedalert(someModule.foo()); // someModule.foo not a function
var someModule = (function() { var x = 5; var foo = function() { return x; } return { bar: function() { return foo(); } }})();
alert(someModule.x); // Undefinedalert(someModule.foo()); // someModule.foo not a function
Public (API)
var someModule = (function() { var x = 5; var foo = function() { return x; } return { bar: function() { return foo(); } }})();
alert(someModule.x); // Undefinedalert(someModule.foo()); // someModule.foo not a functionalert(someModule.bar()); // Alerts 5
// When we call someModule, it’s actually the object literal (JSON) that’s being returned. Since that Object literal still has access to the local variables of someModule, it can give us access to the stuff it wants to and essentially deny us from other stuff
Why Module Pattern
• Good for namespacing• Pseudo Encapsulation (Private and Public)
The term “Module” in this case just means an isolated container of code.
Module Local Scopevar someModule = (function() { var x = 5; // Belongs to the local scope of someModule return { show: function() { alert(x); } }})();
alert(x) // UndefinedsomeModule.show(); // Alerts 5
But it has some drawbacksvar someModule = (function() { var x = 0; // Belongs to the local scope of someModule return { init: function(x) { x = x; // this wont work, will it? }, show: function() { alert(x); } }})();
someModule.init(5);someModule.show(); // Alerts 0, what just happened
But it has some drawbacksvar someModule = (function() { var x = 0; // Belongs to the local scope of someModule return { init: function(x) { x = x; // this wont work, will it? }, show: function() { alert(x); } }})();
someModule.init(5);someModule.show(); // Alerts 0, what just happened
But it has some drawbacksvar someModule = (function() { var x = 0; // Belongs to the local scope of someModule return { init: function(x) { this.x = x; // what if we use “this” }, show: function() { alert(x); } }})();
someModule.init(5);someModule.show(); // Alerts 0, what just happened
But it has some drawbacksvar someModule = (function() { var x = 0; // Belongs to the local scope of someModule return { x: 5, init: function(x) { this.x = x; // what if we use “this” }, show: function() { alert(x); } }})();
someModule.init(5);someModule.show(); // Alerts 0, what just happened
But it has some drawbacks
So that sucks, but moving on…
But it has some drawbacks
• Private and Public methods accessed differently which sucks too
But it has some drawbacksvar someModule = (function() { var x = 2; var foo = function() { return x } // Private Method return { init: function(x) { alert(foo() + bar() + x); }, bar: function() { return 3; } }})();
someModule.init(5) // bar() not defined
But it has some drawbacksvar someModule = (function() { var x = 2; var foo = function() { return x } // Private Method return { init: function(x) { alert(foo() + bar() + x); }, bar: function() { return 3; } }})();
someModule.init(5) // bar() not defined
But it has some drawbacksvar someModule = (function() { var x = 2; var foo = function() { return x } // Private Method return { init: function(x) { alert(foo() + this.bar() + x); }, bar: function() { return 3; } }})();
someModule.init(5) // Alerts 10
Revealing Module Patternmakes it all better
var module = (function() { var priv = function() { … }; return { // Return things you want to be public pub: function() { … } }})();
var revealingModule = (function() { var priv = function() { … }; var pub = function() { … }; return { // Reveal things you want to be public pub: pub }})();
Revealing Module Patternvar someModule = (function() { var x = 2; var foo = function() { return x } // Private Method var init = function(x) alert(foo() + bar() + x); } var bar = function() { return 3; } return { init: init, bar: bar }})();
someModule.init(5) // Alerts 10