// https://addyosmani.com/resources/essentialjsdesignpatterns/book/ // http://benalman.com/news/2010/11/immediately-invoked-function-expression/ // https://carldanley.com/js-facade-pattern/ /// /// The Facade Pattern /// https://carldanley.com/js-facade-pattern/ /// var MyModule = (function(window, undefined) { function myMethod() { alert('my method'); } function myOtherMethod() { alert('my other method'); } // explicitly return public methods when this object is instantiated return { someMethod: myMethod, someOtherMethod: myOtherMethod }; })(window); // example usage MyModule.myMethod(); // undefined MyModule.myOtherMethod(); // undefined MyModule.someMethod(); // alerts "my method" MyModule.someOtherMethod(); // alerts "my other method" /// /// The Facade + Module Pattern Hybrid /// https://addyosmani.com/resources/essentialjsdesignpatterns/book/#facadepatternjavascript /// var module = (function() { var _private = { i: 5, get: function() { console.log("current value:" + this.i); }, set: function(val) { this.i = val; }, run: function() { console.log("running"); }, jump: function() { console.log("jumping"); } }; return { facade: function(args) { _private.set(args.val); _private.get(); if (args.run) { _private.run(); } } }; }()); // Outputs: "current value: 10" and "running" module.facade({run: true, val: 10}); //------------------------------------------------------------------------------ /// /// The Revealing Module Pattern /// https://carldanley.com/js-revealing-module-pattern/ /// var MyModule = (function(window, undefined) { // revealing module pattern ftw function MyModule() { function someMethod() { alert('some method'); } function someOtherMethod() { alert('some other method'); } // expose publicly available methods return { // in our normal revealing module pattern, we'd do the following: someMethod: someMethod, // in the facade pattern, we mask the internals so no one has direct access by doing this: someMethod: function() { someMethod(); } }; } })(window); //------------------------------------------------------------------------------ /// /// Immediately-invoked Function Expressions (IIFE)s /// https://addyosmani.com/resources/essentialjsdesignpatterns/book/ /// NAMESPACE EXTENSION /// // namespace (our namespace name) and undefined are passed here // to ensure 1. namespace can be modified locally and isn't // overwritten outside of our function context // 2. the value of undefined is guaranteed as being truly // undefined. This is to avoid issues with undefined being // mutable pre-ES5. ;(function (namespace, undefined) { // private properties var foo = "foo"; var bar = "bar"; // public methods and properties namespace.foobar = "foobar"; namespace.say = function (msg) { speak(msg); }; namespace.sayHello = function () { namespace.say("hello world"); }; // private method function speak(msg) { console.log("You said: " + msg); }; // check to evaluate whether "namespace" exists in the // global namespace - if not, assign window.namespace an // object literal })(window.namespace = window.namespace || {}); // we can then test our properties and methods as follows // public // Outputs: foobar console.log(namespace.foobar); // Outputs: You said: hello world namespace.sayHello(); // assigning new properties namespace.foobar2 = "foobar"; // Outputs: foobar console.log(namespace.foobar2); /// /// Extensibility is of course key to any scalable namespacing pattern /// // let's extend the namespace with new functionality (function(namespace, undefined) { // public method namespace.sayGoodbye = function () { namespace.say("goodbye"); } })(window.namespace = window.namespace || {}); // Outputs: goodbye namespace.sayGoodbye(); //------------------------------------------------------------------------------ /// /// The Module Pattern, variations /// https://addyosmani.com/resources/essentialjsdesignpatterns/book/ /// IMPORTS /// // Global module var myModule = (function (jQ, _) { function privateMethod1() { jQ(".container").html("test"); } function privateMethod2(){ console.log(_.min([10, 5, 100, 2, 1000])); } return{ publicMethod: function(){ privateMethod1(); } }; })(jQuery, _); // Pull in jQuery and Underscore myModule.publicMethod(); /// /// The Module Pattern, variations /// EXPORTS /// // Global module var myModule = (function () { // Module object var module = {}; var privateVariable = "Hello World"; function privateMethod() { // ... } module.publicProperty = "Foobar"; module.publicMethod = function () { console.log(privateVariable); }; return module; })();