模块化:每一个模块只完成一个独立的功能,而后提供该功能的接口。模块间经过接口访问。模块中的(过程和数据)对于其它模块来讲是私有的(不能访问修改)node
原始人写法:windows
1 function m1(){ 2 //... 3 } 4 function m2(){ 5 //... 6 }
1 var loveThing = { 2 mylove : "coding", 3 getLove :function() { 4 returnthis.mylove; 5 }, 6 sayLove : function(thing) { 7 console.log(thing); 8 } 9 }
1 console.log(loveThing.getLove());//>>> coding 2 loveThing.sayLove('girl');//>>> girl
这种写法已经有点模块的样子了,一下就能看出这几个函数和变量之间的联系。数组
缺点在于全部变量都必须声明为公有,因此都要加this指示做用域以引用这些变量。更危险的是,在对象以外也能轻松更改里面的参数:浏览器
1 loveThing.mylove = "sleeping"; 2 console.log(loveThing.getLove());//>>> sleeping
外部能够访问my这个接口,但如下代码(过程和数据)对于其它模块来讲是私有的安全
如下这种方法返回一个对象,让其余模块去调用异步
1 var loveThing = (function(){ 2 var my = {}; 3 var love = "coding"; 4 my.getLove = function() { 5 return love; 6 } 7 my.sayLove = function(thing) { 8 console.log(thing); 9 } 10 return my; 11 })(); 12 console.log(loveThing.getLove());//>>> coding loveThing.sayLove('reading');//>>> reading
将局部的函数提高到 windows 下面,可让其余地方使用。async
1 (function(){ 2 // private code 3 var a = function(){ 4 5 } 6 window.a = a; 7 })();
咱们试着获取里面的变量:模块化
1 console.log(loveThing.love);//>>> undefined
果真,外部根本看不见里面的零件,只能使用提供的接口。这样才能保证私有变量的安全。 函数
输入全局变量学习
独立性是模块的重要特色,模块内部最好不与程序的其余部分直接交互。为了在模块内部调用全局变量,必须显式地将其余变量输入模块。
下面除了保证模块的独立性,还使得模块之间的依赖关系变得明显。
1 var module1 = (function ($,) { 2 //... 3 })(jQuery,);
CommonJS和AMD
目前,通行的Javascript模块规范共有两种:CommonJS和AMD。
1 var math = require('math');
而后,就能够调用模块提供的方法:
1 var math = require('math'); 2 math.add(2,3); // 5
然而,因为一个重大的局限,使得CommonJS规范不适用于浏览器环境。仍是上一节的代码,若是在浏览器中运行,会有一个很大的问题,你能看出来吗?
第二行math.add(2, 3),在第一行require('math')以后运行,所以必须等math.js加载完成。也就是说,若是加载时间很长,整个应用就会停在那里等。
所以,浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"(asynchronous)。这就是AMD规范诞生的背景。
AMD是"Asynchronous Module Definition"的缩写,意思就是"异步模块定义"。require.js实现了AMD规范
AMD也采用require()语句加载模块,可是不一样于CommonJS,它要求两个参数
require([module], callback);