330 likes | 465 Views
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 () { … })();.
E N D
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 varsomeModule = (function() { … })(); Function Expression Immediate Invoking
The Build-Up function foo() { // Function Declaration … } varfoo = function() { // Function Expression (classy) … } varfoo = function() { // IIFE … }(); varfoo =(function() { // IIFE also … })();
IIFEs are not Closures var person = (function() { })(); // Immediately Invoked varfoo = function(x) { var y = 0; var bar = function bar() { return x; } return bar; // Closure };
IIFEs are not Closures var person = (function() { })(); // Immediately Invoked varfoo = function(x) { var y = 0; var bar = function bar() { return x; } return bar; // Closure }; varsomething = foo(5); // something is a reference to the bar() function
IIFEs are not Closures var person = (function() { })(); // Immediately Invoked varfoo = function(x) { var y = 0; var bar = function bar() { return x; } return bar; // Closure }; varsomething = 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
varsomeModule = (function() { })(); So, back to the Module Pattern
varsomeModule = (function() { var x = 5; })();
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } })();
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return {} // Return Object Literal (JSON) })();
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return {} // Return Object Literal (JSON) })(); {my_num: 3, a: true, thing: ‘some string’} key: value
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return {} // Return Object Literal (JSON) })(); { my_num: 3, a: true, thing: ‘some string’ }
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return {} // Return Object Literal (JSON) })(); { my_num: 3, a: true, thing: ‘some string’, sub_json: {a: 1, b: 23} }
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return {} // Return Object Literal (JSON) })(); { my_num: 3, a: true, thing: ‘some string’, some_function: function() { … } }
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return { } })();
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return { bar: function() { return foo(); } } })();
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return { bar: function() { return foo(); } } })(); alert(someModule.x); // Undefined Private (ish)
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return { bar: function() { return foo(); } } })(); alert(someModule.x); // Undefined alert(someModule.foo()); // someModule.foo not a function
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return{ bar: function() { return foo(); } } })(); alert(someModule.x); // Undefined alert(someModule.foo()); // someModule.foo not a function Public (API)
varsomeModule = (function() { var x = 5; varfoo = function() { return x; } return { bar: function() { return foo(); } } })(); alert(someModule.x); // Undefined alert(someModule.foo()); // someModule.foo not a function alert(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 Scope varsomeModule = (function() { var x = 5; // Belongs to the local scope of someModule return { show: function() { alert(x); } } })(); alert(x) // Undefined someModule.show(); // Alerts 5
But it has some drawbacks varsomeModule = (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 drawbacks varsomeModule = (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 drawbacks varsomeModule = (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 drawbacks varsomeModule = (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 drawbacks varsomeModule = (function() { var x = 2; varfoo = 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 drawbacks varsomeModule = (function() { var x = 2; varfoo = 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 drawbacks varsomeModule = (function() { var x = 2; varfoo = 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() { varpriv = function() { … }; return { // Return things you want to be public pub: function() { … } } })(); varrevealingModule = (function() { varpriv = function() { … }; var pub = function() { … }; return { // Reveal things you want to be public pub: pub } })();
Revealing Module Pattern varsomeModule = (function() { var x = 2; varfoo = 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