就比如寫書的做者同樣,會把一本書分紅一個個的章節,再把每一章的內容分紅若干節,而後構建成一本完整的書,讓書更加有條理性和可閱讀性。而做爲一個程序員,就能夠把代碼分紅一些模塊,而後組成一個完整的「功能」javascript
(function(){ //在函數的做用域中下面的變量是私有的 var myGrades = [93,95,88,0,55,97]; var average = function(){ var total = myGrades.reduce(function(accumulator,item){ return accumulator+item; },0) return 'Your average grade is ' + total / myGrades.length + '.'; } var failing = function(){ var failingGrades = myGrades.filter(function(item){ return item < 70; }) return "you failed" + failingGrades.length + 'times.'; } console.log(failing()); //You failed 2 times. }());
(function (globalVariable) { // 在函數的做用域中下面的變量是私有的 var privateFunction = function() { console.log('this is private!'); } // 經過全局變量設置下列方法的外部訪問接口 // 與此同時這些方法又都在函數內部 globalVariable.each = function(collection, iterator) { if (Array.isArray(collection)) { for (var i = 0; i < collection.length; i++) { iterator(collection[i], i, collection); } } else { for (var key in collection) { iterator(collection[key], key, collection); } } }; globalVariable.filter = function(collection, test) { var filtered = []; globalVariable.each(collection, function(item) { if (test(item)) { filtered.push(item); } }); return filtered; }; globalVariable.map = function(collection, iterator) { var mapped = []; globalUtils.each(collection, function(value, key, collection) { mapped.push(iterator(value)); }); return mapped; }; }(globalVariable));
globalVariable
是惟一一個全局變量,這種作法比徹底匿名的閉包的好處是,代碼結構更清晰,並且性能更好。咱們可以看到函數內部傳遞進來了全局變量,因此依賴關係很是清晰。其次在函數內部調用 globalVarible
的時候,解釋器可以直接找到局部的 globalVarible
,就不用上溯到外部的 globalVarible
.var myGradesCalculate = (function(){ var myGrades = [93,95,88,0,55,97]; // 經過接口在外部訪問下列方法 // 與此同時這些方法又都在函數內部 return { average: function(){ var total = myGrades.reduce(function(accumulator,item){ return accumulator+item; },0); return 'Your average grade is ' + total / myGrades.length + '.'; }, failing: function() { var failingGrades = myGrades.filter(function(item) { return item < 70; }); return 'You failed ' + failingGrades.length + ' times.'; } } })(); myGradesCalculate.failing(); // 'You failed 2 times.' myGradesCalculate.average(); // 'Your average grade is 71.33333333333333.'
var myGradesCalculate = (function () { var myGrades = [93, 95, 88, 0, 55, 91]; var average = function() { var total = myGrades.reduce(function(accumulator, item) { return accumulator + item; }, 0); return'Your average grade is ' + total / myGrades.length + '.'; }; var failing = function() { var failingGrades = myGrades.filter(function(item) { return item < 70; }); return 'You failed ' + failingGrades.length + ' times.'; }; // 將公有指針指向私有方法 return { average: average, failing: failing } })(); myGradesCalculate.failing(); // 'You failed 2 times.' myGradesCalculate.average(); // 'Your average grade is 71.33333333333333.'
上面這些方法都有一個共同點:使用一個特定的全局模塊名來把一些私有變量和方法包起來,而後經過閉包來建立一個私有的命名空間。html
缺點:java
作法: 經過module.exports
對象暴露對外接口。經過require()
進行調用
典例: Node.js程序員
優點:web
特色:編程
劣勢:數組
使用方式:瀏覽器
define([moduleA,moduleB],function(moduleA,moduleB){ console.log(moduleA.hello()); });
appendChild
將這兩個模塊插入到DOM
中。在兩個模塊都加載成功以後,define 會調用第二個參數中的回調函數,通常是函數主體。define
既是一種引用模塊的方式,也是定義模塊的方式//moduleA define([],function(){ return { hello: function(){ console.log('hello'); }, goodbye: function(){ console.log('bye'); } } });
特色:服務器
對於須要同時支持 AMD
和 CommonJS
的模塊而言,可使用 UMD,而且UMD指出全局變量定義,因此UMD能夠同時在客戶端和服務端使用網絡
(function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD define(['myModule', 'myOtherModule'], factory); } else if (typeof exports === 'object') { // CommonJS module.exports = factory(require('myModule'), require('myOtherModule')); } else { // Browser globals (Note: root is window) root.returnExports = factory(root.myModule, root.myOtherModule); } }(this, function (myModule, myOtherModule) { // Methods function notHelloOrGoodbye(){}; // A private method function hello(){}; // A public method because it's returned (see below) function goodbye(){}; // A public method because it's returned (see below) // Exposed public methods return { hello: hello, goodbye: goodbye } }));
//CommonJS // lib/counter.js var counter = 1; function increment() { counter++; } function decrement() { counter--; } module.exports = { counter: counter, increment: increment, decrement: decrement }; // src/main.js var counter = require('../../lib/counter'); counter.increment(); console.log(counter.counter); // 1
//import // lib/counter.js export let counter = 1; export function increment() { counter++; } export function decrement() { counter--; } // src/main.js import * as counter from '../../counter'; console.log(counter.counter); // 1 counter.increment(); console.log(counter.counter); // 2
JavaScript模塊化編程簡史(2009-2016)
JavaScript 模塊化入門Ⅰ:理解模塊
JavaScript Modules: A Beginner’s Guide
深刻理解JavaScript系列(3):全面解析Module模式