模块化开发
学习目标:
模块化开发的必要性
模块化的写法历史
AMD规范
require.js用法
request.js的应用
一、JavaScript模块化的必要性
随着网站逐渐变成"互联网应用程序(WebApp)",嵌入网页的Javascript代码越来越庞大,越来越复杂。
网页越来越像桌面程序,需要一个团队分工协作、进度管理、单元测试等等…开发者不得不使用软件工程的方法,管理网页的业务逻辑。
Javascript模块化编程,已经成为一个迫切的需求。理想情况下,开发者只需要实现核心的业务逻辑,其他都可以加载别人已经写好的模块。
但是,Javascript不是一种模块化编程语言,它不支持"类"(class),更遑论"模块"(module)了。(正在制定中的ECMAScript标准第六版,将正式支持"类"和"模块",但还需要很长时间才能投入实用。)
Javascript社区做了很多努力,在现有的运行环境中,实现"模块"的效果。
二、Javascript模块化的写法
2.1 原始写法
模块就是实现特定功能的一组方法。
只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块。比如:tool.js:
function m1(){
}
function m2(){
}
- 上面的函数m1()和m2(),组成一个模块。使用的时候,直接调用就行了。
- 缺点明显:"污染"了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。
2.2 对象写法
为了解决上面的缺点,可以把模块写成一个对象,所有的模块成员都放到这个对象里面。
var moduleA = {
count: 100,
showA: function(){
this.count += 10;
alert(this.count);
},
showB: function(){
this.count *= 20;
alert(this.count);
}
};
var moduleB = {
count: 50,
showA: function(){
this.count += 100;
alert(this.count);
},
showB: function(){
this.count /= 20;
alert(this.count);
}
};
moduleA.count = "hello";
moduleA.showA();
moduleA.showB();
moduleB.showA();
moduleB.showB();
- 缺点:暴露所有模块成员,内部状态可以被外部改写。比如,外部函数可以直接改变_count的值。
- 我们希望可以进行私有化。
2.3 立即执行函数写法(闭包)
使用"立即执行函数"(Immediately-Invoked Function Expression,IIFE),可以达到不暴露私有成员的目的。
- (函数声明)(函数调用)
var moduleA = (function(){
var count = 10; //私有变量
function showA(){ //私有函数
count += 20;
alert(count);
}
function showB(){
count *= 10;
alert(count);
}
//对外暴露
return {
outA: showA,
ou