模块模式可以提供软件架构,为不断增长的代码提供组织形式。JavaScript没有提供package的语言表示,但我们可以通过模块模式来分解并组织 代码块,这些黑盒的代码块内的功能可以根据不断变化的软件需求而不断的被添加,替代和删除。模块模式由几种我们已经介绍过的模式共同组成:

  • 命名空间模式
  • 即时函数模式
  • 私有成员与访问控制方法模式
  • 依赖声明模式
模块模式的第一步是建立一个命名空间。首先我们用先前介绍的namespace()方法创建一个工具模块例子,这个例子模块提供一些数组功能:
MYAPP.namespace('MYAPP.utilities.array');
下一步就是定义这个模块。模块模式使用即时函数中的局部作用域来存放私有代码段。即时函数返回一个对象,该对象实际上就是被定义模块的公用接口,使用该模块的程序员可以通过这个对象来获得该模块提供的功能:
MYAPP.utilities.array = (function () {
return {
// todo...
};
}());
下面为这个模块增加一些公有的方法:
MYAPP.utilities.array = (function () {
return {
inArray: function (needle, haystack) {
// ...
},
isArray: function (a) {
// ...
}
};
}());
利用即时函数提供的局部作用域,可以在即时函数体的上部,给出模块的依赖关系,私有属性,以及需要初始化的代码。最后,这个即时函数返回需要创建的模块的公有访问接口对象:
MYAPP.namespace('MYAPP.utilities.array');
MYAPP.utilities.array = (function () {
// dependencies
var uobj = MYAPP.utilities.object,
ulang = MYAPP.utilities.lang,
// private properties
array_string = "[object Array]",
ops = Object.prototype.toString;
// private methods
// ...
// end var
// optionally one-time init procedures
// ...
// public API
return {
inArray: function (needle, haystack) {
for (var i = 0, max = haystack.length; i < max; i += 1) {
if (haystack[i] === needle) {
return true;
}
}
},
isArray: function (a) {
return ops.call(a) === array_string;
}
// ... more methods and properties
};
}());
以上就是模块模式的基本思路。模块模式是组织JavaScript代码的常用模式,推荐在软件开发中经常使用。
1. 通过揭露模式创建的模块
上面的模块模式例子中,公有方法是直接声明的。结合之前介绍的揭露模式,可以把所有模式中的方法都先声明为私有,然后再通过揭露模式,把私有的方法通过公有的接口方法展示出来。据此,上面的例子可以这样写:
MYAPP.utilities.array = (function () {
// private properties
var array_string = "[object Array]",
ops = Object.prototype.toString,
// private methods
inArray = function (haystack, needle) {
for (var i = 0, max = haystack.length; i < max; i += 1) {
if (haystack[i] === needle) {
return i;
}
}
return ?1;
},
isArray = function (a) {
return ops.call(a) === array_string;
};
// end var
// revealing public API
return {
isArray: isArray,
indexOf: inArray
};
}());
2. 通过构造函数创建的模块
以上的例子中都是直接返回对象,有时候使用构造函数要更方便一些。使用构造函数的模块模式与上面例子的区别就在于返回的是一个函数,而不是一个字面声明的对象:
MYAPP.namespace('MYAPP.utilities.Array');
MYAPP.utilities.Array = (function () {
// dependencies
var uobj = MYAPP.utilities.object,
ulang = MYAPP.utilities.lang,
// private properties and methods...
Constr;
// end var
// optionally one-time init procedures
// ...
// public API -- constructor
Constr = function (o) {
this.elements = this.toArray(o);
};
// public API -- prototype
Constr.prototype = {
constructor: MYAPP.utilities.Array,
version: "2.0",
toArray: function (obj) {
for (var i = 0, a = [], len = obj.length; i < len; i += 1) {
a[i] = obj[i];
}
return a;
}
};
// return the constructor
// to be assigned to the new namespace
return Constr;
}());
使用构造函数来声明的模块,可以这样调用:
var arr = new MYAPP.utilities.Array(obj);

3. 把global对象引入到模块中

模块声明时使用的即时函数可以接受需要的参数,这些参数可以根据设计的需要来引入。一个常用的做法是把global作为参数引入进来,这样全局对象就本地化了(Localized),可以加速对全局变量的访问:
MYAPP.utilities.module = (function (app, global) {
// references to the global object
// and to the global app namespace object
// are now localized
}(MYAPP, this));

JavaScript基础对象创建模式之模块模式(Module Pattern)(025)的更多相关文章

  1. JavaScript基础对象创建模式之命名空间(Namespace)模式(022)

    JavaScript中的创建对象的基本方法有字面声明(Object Literal)和构造函数两种,但JavaScript并没有特别的语法来表示如命名空间.模块.包.私有属性.静态属性等等面向对象程序 ...

  2. JavaScript基础对象创建模式之私有属性和方法(024)

    JavaScript没有特殊的语法来表示对象的私有属性和方法,默认的情况下,所有的属性和方法都是公有的.如下面用字面声明的对象: var myobj = { myprop: 1, getProp: f ...

  3. JavaScript基础对象创建模式之单体/单例模式(Singleton)

    首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点: 1,该类只有一个实例 2,该类自行创建该实例(在该类内部创建自身的实例对象) 3,向整个系统公开这个实例接口 Java中大 ...

  4. JavaScript基础对象创建模式之沙盘模式(026)

    沙盘模式可以弥补命名空间模式中的两项不足之处: 使用唯一全局对象作为程序的全局变量入口,使得无法在同一程序中使用两个不同版本的API,因此它们使用的是同一个唯一的全局对象名,如MYAPP: 较长的嵌套 ...

  5. JavaScript基础对象创建模式之声明依赖模式(023)

    运用了命名空间(Namespace)模式后, 就可以使用一些JavaScript库了,比如YAHOO作用YUI2库的全局对象,可以通过 YAHOO.util.Dom 和 YAHOO.util.Even ...

  6. JavaScript基础对象创建模式之链式调用模式(Chaining Pattern)(029)

    链式调用模式允许一个接一个地调用对象的方法.这种模式不考虑保存函数的返回值,所以整个调用可以在同一行内完成: myobj.method1("hello").method2().me ...

  7. JavaScript基础对象创建模式之静态成员(027)

    在支持“类”的面向对象语言中,静态成员指的是那些所有实例对象共有的类成员.静态成员实际是是“类”的成员,而非“对象”的成员.所以如果 MathUtils类中有个叫 max()的静态成员方法,那么调用这 ...

  8. JavaScript基础对象创建模式之对象的常量(028)

    虽然许多编程语言提供了const关键字来支持常量的声明,但JavaScript里没有表示常量的语义.我们可以用全大写的方式来声明变量,表明它实际上是个常量: Math.PI; // 3.1415926 ...

  9. 初涉JavaScript模式 (11) : 模块模式

    引子 这篇算是对第9篇中内容的发散和补充,当时我只是把模块模式中的一些内容简单的归为函数篇中去,在北川的提醒下,我才发觉这是非常不严谨的,于是我把这些内容拎出来,这就是这篇的由来. 什么是模块模式 在 ...

随机推荐

  1. ASP.NET中IHttpHandler与IHttpModule的区别(带样例说明)

    IHttpModule相对来说,是一个网页的添加 IHttpHandler相对来说,却是网页的替换 先建一个HandlerDemo的类 using System; using System.Colle ...

  2. Java实现 LeetCode 567 字符串的排列(滑动窗口,处理区间内的字符数量)

    567. 字符串的排列 给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列. 换句话说,第一个字符串的排列之一是第二个字符串的子串. 示例1: 输入: s1 = " ...

  3. Java实现 LeetCode 344 反转字符串

    344. 反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 char[] 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间 ...

  4. Java实现 LeetCode 166 分数到小数

    166. 分数到小数 给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数. 如果小数部分为循环小数,则将循环的部分括在括号内. 示例 1: 输入 ...

  5. Java实现 LeetCode 105 从前序与中序遍历序列构造二叉树

    105. 从前序与中序遍历序列构造二叉树 根据一棵树的前序遍历与中序遍历构造二叉树. 注意: 你可以假设树中没有重复的元素. 例如,给出 前序遍历 preorder = [3,9,20,15,7] 中 ...

  6. java实现连续数的公倍数

    为什么1小时有60分钟,而不是100分钟呢?这是历史上的习惯导致. 但也并非纯粹的偶然:60是个优秀的数字,它的因子比较多. 事实上,它是1至6的每个数字的倍数.即1,2,3,4,5,6都是可以除尽6 ...

  7. Python之Flask框架二

    今天接着上一篇继续写一篇关于flask的随笔. 本文大纲: 1.获取请求参数 2.一个函数处理多个请求方式 3.重定向 4.错误响应 5.全局错误处理 6.返回json格式数据 7.自定义返回内容状态 ...

  8. android在service中stopself遇到的问题

    在service的oncreate中直接调用stopservice停止自己,依然会执行onstartcommand方法后,最后才调用ondestory方法

  9. Nice Jquery Validator 快速上手

    (1).直接引用 一行代码引入插件,local 参数用来加载对应的配置文件.如果不传 local 参数,配置以及样式就需要自行引入. <script src="path/to/nice ...

  10. 关于JSON数据体积优化的一点小心得

    最近在做的一个项目里传输的json数据比较大,造成了线程间的卡顿,于是想优化一下json数据的体积. 可以看到在json文件里有很多无用的字段,这些字段占据了大量的存储空间. 对数据的结构作一下优化, ...