如今backbone、emberjs、spinejs、batmanjs 等MVC框架侵袭而来。CommonJS、AMD、NodeJS、RequireJS、SeaJS、curljs等模块化的JavaScript扑面而来。web前端已经演变成大前端,web前端的发展速度之快。
模块化是一种将系统分离成独立功能部分的方法,可将系统分割成独立的功能部分,严格定义模块接口、模块间具有透明性。javascript中的模块在一些C、PHP、java中比较常见:
- c中使用include 包含.h文件;
- php中使用require_once包含.php文件
- java使用import导入包
优点:
可维护性
1.灵活架构,焦点分离
2.方便模块间组合、分解
3.方便单个模块功能调试、升级
4.多人协作互不干扰
可测试性
1.可分单元测试
缺点:
性能损耗
1.系统分层,调用链会很长
2.模块间通信,模块间发送消息会很耗性能
模块模式
1.匿名闭包函数
(function () {
//下面的变量是私有的
var name="xwk";
var age="23";
var say=function () {
return name+"的年龄是"+age;
};
console.log(say())
}());
通过这种构造,匿名函数形成了闭包,使得父作用域即全局里面访问不到里面的变量,好处是隔离了全局中的变量,不会出现同名污染
2.全局引入
与上面所介绍的匿名闭包函数差不多,只不过,将全局变量以参数的形式传入到函数中,jquery的封装就是如此
(function(globalVariable){
...
}
(globalVariable))
3.对象接口
var globalObj=(function () {
return {
func1:function () {
return "r1";
},
func2:function () {
return "r2";
}
}
})();
console.log(globalObj.func1())
commonJS & AMD模式
1.commonJs
CommonJS模块可以很方便得将某个对象导出,让他们能够被其他模块通过 require 语句来引入。要是你写过 Node.js 应该很熟悉这些语法。
通过CommonJS,每个JS文件独立地存储它模块的内容(就像一个被括起来的闭包一样)。在这种作用域中,我们通过 module.exports 语句来导出对象为模块,再通过 require 语句来引入。
function module1() {
this.name=function () {
return "xwk";
};
this.age=function () {
return "23";
}
}
module.exports = module1;
如果想要引用时,只需要require一下
var m1=require("module1");
var module1=new m1();
module1.name();
module1.age();
这种实现比起模块模式有两点好处:
注意!!!
使用commonJs模式,是以服务器优先的模式来同步加载模块,假如我们加载3个模块,这3个模块将一个个的依次载入,缺点就是对浏览器端不太友好,只要他还在加载模块,页面就会一直卡着不动直到模块加载完成。
2.AMD模式
CommonJS已经挺不错了,但假使我们想要实现异步加载模块该怎么办?答案就是Asynchronous Module Definition(异步模块定义规范),简称AMD.
通过AMD载入模块的代码一般这么写:
define(["module1","module2"],function(module1,module2){
console.log(module.hello())
});
//define方法,第一个参数是与之依赖的模块数组(注意是数组,如果没有,用[]表示),第二个参数是一个模块加载完成的回调函数,回调函数的参数是我们引入的模块
这些模块本身也需要用define声明,例如module1模块:
define([],function(){
return {
func1:function () {
return "r1";
},
func2:function () {
return "r2";
}
}
});
除了异步加载以外,AMD的另一个优点是你可以在模块里使用对象、函数、构造函数、字符串、JSON或者别的数据类型,而CommonJS只支持对象。
3.UMD模式
UMD创造了一种同时使用两种规范的方法,并且也支持全局变量定义。所以UMD的模块可以同时在客户端和服务端使用。由于我也没用过,这里将不在详细介绍。。。。
RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一。
基本api
equire会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短。
- define 从名字就可以看出这个api是用来定义一个模块
- require 加载依赖模块,并执行加载完后的回调函数