JavaScript 模块模式
1. 对象字面量
1 var myObjectLiteral = { 2 3 variableKey: variableValue, 4 5 functionKey: function () { 6 // ... 7 } 8 };
示例如下:
1 var myModule = { 2 3 myProperty: "someValue", 4 5 // object literals can contain properties and methods. 6 // e.g we can define a further object for module configuration: 7 myConfig: { 8 useCaching: true, 9 language: "en" 10 }, 11 12 // a very basic method 13 saySomething: function () { 14 console.log( "Where in the world is Paul Irish today?" ); 15 }, 16 17 // output a value based on the current configuration 18 reportMyConfig: function () { 19 console.log( "Caching is: " + ( this.myConfig.useCaching ? "enabled" : "disabled") ); 20 }, 21 22 // override the current configuration 23 updateMyConfig: function( newConfig ) { 24 25 if ( typeof newConfig === "object" ) { 26 this.myConfig = newConfig; 27 console.log( this.myConfig.language ); 28 } 29 } 30 }; 31 32 // Outputs: Where in the world is Paul Irish today? 33 myModule.saySomething(); 34 35 // Outputs: Caching is: enabled 36 myModule.reportMyConfig(); 37 38 // Outputs: fr 39 myModule.updateMyConfig({ 40 language: "fr", 41 useCaching: false 42 }); 43 44 // Outputs: Caching is: disabled 45 myModule.reportMyConfig();
2. 模块模式
1 var testModule = (function () { 2 var counter = 0; // 私有变量 3 return { 4 incrementCounter: function () { 5 /// <summary> 6 /// 增加计数 7 /// </summary> 8 return ++counter; 9 }, 10 resetConter: function () { 11 /// <summary> 12 /// 重置计数 13 /// </summary> 14 counter = 0; 15 } 16 } 17 })(); 18 19 // 使用 20 testModule.incrementCounter(); 21 testModule.resetConter();
包括命名空间、私有、共有变量的模块:
1 var myNamespace = (function () { 2 // 私有 3 var myPrivateVar = 0; 4 var myPrivateMethod = function (foo) { 5 console.log(foo); 6 }; 7 8 return { 9 // 公有变量 10 myPublicVar: 'foo', 11 12 //调用私有变量和方法的公有函数 13 myPublicFunction: function (bar) { 14 myPrivateVar++; // 增加自由的计数器的值 15 myPrivateMethod(bar); // 传入bar调用私有方法 16 } 17 }; 18 })();
1 var basketModule = (function () { 2 // 私有变量 3 var basket = []; 4 5 function doSomethingPrivate() { 6 // ... 7 } 8 9 function doSomethingElsePrivate() { 10 // ... 11 } 12 13 // 返回一个暴露出的公有对象 14 return { 15 addItem: function (values) { 16 /// <summary> 17 /// 添加item到购物车 18 /// </summary> 19 /// <param name="values"></param> 20 basket.push(values); 21 }, 22 getItemCount: function () { 23 /// <summary> 24 /// 获取购物车里的item数 25 /// </summary> 26 return basket.length; 27 }, 28 // 私有函数的公有形式别名 29 doSomething: doSomethingPrivate, 30 getTotal: function () { 31 /// <summary> 32 /// 获取购物车里所有item的价格总值 33 /// </summary> 34 var itemCount = this.getItemCount(), 35 total = 0; 36 while (itemCount--) { 37 total += basket[itemCount].price; 38 } 39 return total; 40 } 41 }; 42 43 }()); 44 45 basketModule.addItem({ item: '面包', price: 5 }); 46 basketModule.addItem({ item: '黄油', price: 8 }); 47 console.log(basketModule.getItemCount()); 48 console.log(basketModule.getTotal());
3. 揭示模块模式
1 var myRevealingModule = (function () { 2 3 var privateCounter = 0; 4 5 function privateFunction() { 6 privateCounter++; 7 } 8 9 function publicFunction() { 10 publicIncrement(); 11 } 12 13 function publicIncrement() { 14 privateFunction(); 15 } 16 17 function publicGetCount(){ 18 return privateCounter; 19 } 20 21 // Reveal public pointers to 22 // private functions and properties 23 24 return { 25 start: publicFunction, 26 increment: publicIncrement, 27 count: publicGetCount 28 }; 29 30 })(); 31 32 myRevealingModule.start();
4. 更多模块模式的代码
/* 匿名闭包 */ (function () { var MyAPP = { version: '0.0.1' }; MyAPP.print = function () { console.log(MyAPP.version); }; MyAPP.print(); }()); /* 全局导入(Global Import) */ (function ($, YAHOO) { var MyAPP = { version: '0.0.1' }; MyAPP.print = function () { console.log(MyAPP.version); }; MyAPP.print(); $(function () { $('body').html(MyAPP.version); }); }(jQuery, YAHOO)); /* 模块导出(Module Export) */ var MODULE = (function () { var MyAPP = {}, privateVariable = 1; function privateMethod() { /// <summary> /// 私有方法 /// </summary> // ... } MyAPP.moduleProperty = 1; MyAPP.moduleMethod = function () { // ... }; return MyAPP; }()); /* 高级模块模式 */ // Augmentation(augment modules.) var MODULE = (function (my) { my.anotherMethod = function () { // added method... }; return my; }(MODULE)); /* 松耦合扩展 */ var MODULE = (function (my) { // 添加方法 return my; }(MODULE || {})); /* 紧耦合扩展 */ var MODULE = (function (my) { var oldModuleMethod = my.moduleMethod; // 重写模块方法 my.moduleMethod = function () { // 方法重写,此处可以通过oldModuleMethod访问老方法 }; return my; }(MODULE)); /* 克隆和继承 */ var MODULE_TWO = (function (old) { var NewApp = {}, key; for (key in old) { if (old.hasOwnProperty(key)) { NewApp[key] = old[key]; } } var super_moduleMethod = old.moduleMethod; NewApp.moduleMethod = function () { // override method on the clone, access to super through super_moduleMethod }; return NewApp; }(MODULE)); /* 跨文件私有状态 */ var MODULE = (function (my) { var _private = my._private = my._private || {}, _seal = my._seal = my._seal || function () { delete my._private; delete my._seal; delete my._unseal; }, _unseal = my._unseal = my._unseal || function () { my._private = _private; my._seal = _seal; my._unseal = _unseal; }; // permanent(永久) access to _private, _seal, and _unseal return my; }(MODULE || {})); /* 子模块 */ MODULE.sub = (function () { var my = {}; // ... return my; }()); /* 组合使用 */ var UTIL = (function (parent, $) { var my = parent.ajax = parent.ajax || {}; my.get = function (url, params, callback) { return $.getJSON(url, params, callback); }; // etc... return parent; }(UTIL || {}, jQuery));
参考自:
http://drakeleung.github.io/blog/2016/02/07/JavaScript-Module-A-Beginner-Guide/
https://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript
http://www.adequatelygood.com/JavaScript-Module-Pattern-In-Depth.html