Module Pattern
文章目录

模块化模式

首先我们来看看Module模式的基本特征:

  1. 模块化,可重用
  2. 封装了变量和function,和全局的namaspace不接触,松耦合
  3. 只暴露可用public的方法,其它私有方法全部隐藏

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
var Calculator = function (eq) {
//这里可以声明私有成员

var eqCtl = document.getElementById(eq);

return {
// 暴露公开的成员
add: function (x, y) {
var val = x + y;
eqCtl.innerHTML = val;
}
};
};


var calculator = new Calculator('eq');
calculator.add(2, 2);

匿名闭包

1
2
3
4
(function () {
// ... 所有的变量和function都在这里声明,并且作用域也只能在这个匿名闭包里
// ...但是这里的代码依然可以访问外部全局的对象
}());

注意,匿名函数后面的括号,这是JavaScript语言所要求的,因为如果你不声明的话,JavaScript解释器默认是声明一个function函数,有括号,就是创建一个函数表达式,也就是自执行,用的时候不用和上面那样在new了,当然你也可以这样来声明:

1
(function () {/* 内部代码 */})();

引用全局变量

获取全局变量到匿名函数域

1
2
3
(function ($, YAHOO) {
// 这儿$相当于全局的jQuery
} (jQuery, YAHOO));//这两个是全局变量, 我们把它们放到这儿说明使用这两个参数调用上面那个匿名函数

从匿名函数域设定全局变量

1
2
3
4
5
var blogModule = (function () {
var my = [1,2,3]

return my;//其实只要把这些变量返回回去就行了, 之后blogModule就相当于my这个变量
} ());

当然return也可以返回一个object

1
2
3
4
5
6
7
8
var blogModule = (function () {
var my = [1,2,3]

return {
my: my,
you: null
}
} ());

高级用法

对变量自身进行扩展

1
2
3
4
5
6
7
var blogModule = (function (my) { // 2. 这里接收到了传进来的blogModule并把blogModule命名为my
var AddPhoto = function () { // 3. 这里给my添加了个函数, 因此blogModule也多了个函数
console.log(123);
};
return {AddPhoto: AddPhoto};
} (blogModule)); //1. 这里将blogModule传了进去
blogModule.AddPhoto()// 4. 扩展完毕后就可以调用了

松耦合扩展

上面的扩展必须要先定义这个blogModule, 能否在未定义的时候初始化而在已定义的时候直接扩展来达到松耦合的目的呢:

1
2
3
4
5
6
var blogModule = (function (my) {

// 添加一些功能

return my;
} (blogModule || {}));

这样可以英一顺序加载module模式

紧耦合扩展

虽然松耦合扩展很牛叉了,但是可能也会存在一些限制,比如你没办法重写你的一些属性或者函数,也不能在初始化的时候就是用Module的属性。紧耦合扩展限制了加载顺序,但是提供了我们重载的机会,看如下例子:

1
2
3
4
5
6
7
8
9
var blogModule = (function (my) {
var oldAddPhotoMethod = my.AddPhoto;

my.AddPhoto = function () {
// 重载方法,依然可通过oldAddPhotoMethod调用旧的方法
};

return my;
} (blogModule));

子模块

1
2
3
4
5
6
blogModule.CommentSubModule = (function () {
var my = {};
// ...

return my;
} ());