Interchangeable single-parts of a larger system that can be easily re-used.
Stepping stone: IIFE
Immediately invoked function expressions (or self-executing anonymous functions)
123456789101112131415
(function(){// code to be immediately invoked}());// Crockford recommends this way(function(){// code to be immediately invoked})();// This is just as valid(function(window,document,undefined){//code to be immediately invoked})(this,this.document);(function(global,undefined){//code to be immediately invoked})(this);
Simulate privacy
The typical module pattern is where immediately invoked function expressions (IIFEs) use execution context to create ‘privacy’. Here, objects are returned instead of functions.
123456789101112131415161718
varbasketModule=(function(){varbasket=[];//privatereturn{//exposed to publicaddItem:function(values){basket.push(values);},getItemCount:function(){returnbasket.length;},getTotal:function(){varq=this.getItemCount(),p=0;while(q--){p+=basket[q].price;}returnp;}}}());
In the pattern, variables declared are only available inside the module.
Variables de ned within the returning object are available to everyone
This allows us to simulate privacy
Sample usage
Inside the module, you’ll notice we return an object. This gets automatically assigned to basketModule so that you can interact with it as follows:
123456789101112
//basketModule is an object with properties which can also be methodsbasbasketModule.addItem({item:'bread',price:0.5});basketModule.addItem({item:'butter',price:0.3});console.log(basketModule.getItemCount());console.log(basketModule.getTotal());//however, the following will not work:// (undefined as not inside the returned object)console.log(basketModule.basket);//(only exists within the module scope)console.log(basket);
Module Pattern: jQuery
In the following example, a library function is defined which declares a new library and automatically binds up the init function to document.ready when new libraries (ie. modules) are created.
A very simple AMD module using jQuery and the color plugin
12345678910111213
define(["jquery","jquery.color","jquery.bounce"],function($){//the jquery.color and jquery.bounce plugins have been loaded// not exposed to other modules$(function(){$('#container').animate({'backgroundColor':'#ccc'},500).bounce();});// exposed to other modulesreturnfunction(){// your modules functionality};});
AMD/UMD jQuery Plugin
Recommended by Require.js author James Burke
1234567891011121314151617
(function(root,factory){if(typeofexports==='object'){// Node/CommonJSfactory(require('jquery'));}elseif(typeofdefine==='function'&&define.amd){// AMD. Use a named plugin in case this// file is loaded outside an AMD loader,// but an AMD loader lives on the page.define('myPlugin',['jquery'],factory);}else{// Browser globalsfactory(root.jQuery);}}(this,function($){$.fn.myPlugin=function(){};}));
CommonJS Modules
They basically contain two parts: an exports object that contains the objects a module wishes to expose and a require function that modules can use to import the exports of other modules
1234567891011
/* here we achieve compatibility with AMD and CommonJSusing some boilerplate around the CommonJS module format*/(function(define){define(function(require,exports){/*module contents*/vardep1=require("foo");vardep2=require("bar");exports.hello=function(){...};exports.world=function(){...};});})(typeofdefine=="function"?define:function(factory){factory(require,exports)});
2. Facade Pattern
Convenient, high-level interfaces to larger bodies of code that hide underlying complexity
Facade Implementation
A higher-level facade is provided to our underlying module, without directly exposing methods.
12345678910111213141516171819202122232425
varmodule=(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();}}}}());module.facade({run:true,val:10});//outputs current value: 10, running
3. Mediator Pattern
Encapsulates how disparate modules interact with each other by acting as an intermediary
Mediator Implementation
One possible implementation, exposing publish and subscribe capabilities.
//Pub/sub on a centralized mediatormediator.name="tim";mediator.subscribe('nameChange',function(arg){console.log(this.name);this.name=arg;console.log(this.name);});mediator.publish('nameChange','david');//tim, david//Pub/sub via third party mediatorvarobj={name:'sam'};mediator.installTo(obj);obj.subscribe('nameChange',function(arg){console.log(this.name);this.name=arg;console.log(this.name);});obj.publish('nameChange','john');//sam, john
Form http://www.slideshare.net/AddyOsmani/futureproofing-your-javascript-apps-compact-edition