就比如写书的做者同样,会把一本书分红一个个的章节,再把每一章的内容分红若干节,而后构建成一本完整的书,让书更加有条理性和可阅读性。而做为一个程序员,就能够把代码分红一些模块,而后组成一个完整的“功能”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模式