JavaScript基础对象创建模式之模块模式(Module Pattern)(025)

模块模式可以提供软件架构,为不断增长的代码提供组织形式。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));
时间: 2024-10-26 08:22:55

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

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

JavaScript中的创建对象的基本方法有字面声明(Object Literal)和构造函数两种,但JavaScript并没有特别的语法来表示如命名空间.模块.包.私有属性.静态属性等等面向对象程序设计中的概 念.为了让JavaScript实现面向对象程序中的高级语义,人们发明了命名空间模式.依赖声明模式,模块模式,以及沙盘模式. 1. 命名空间模式 命 名空间模式解决了JavaScript中的两个问题,一是全局变量污染的问题,二是可能的名字冲突问题.虽然JavaScript没有特别支持命名空

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

JavaScript没有特殊的语法来表示对象的私有属性和方法,默认的情况下,所有的属性和方法都是公有的.如下面用字面声明的对象: var myobj = { myprop: 1, getProp: function () { return this.myprop; } }; console.log(myobj.myprop); // `myprop` is publicly accessible console.log(myobj.getProp()); // getProp() is publ

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

运用了命名空间(Namespace)模式后, 就可以使用一些JavaScript库了,比如YAHOO作用YUI2库的全局对象,可以通过 YAHOO.util.Dom 和 YAHOO.util.Event得到YUI2库中有关Dom和事件的支持.在程序中使用这些模块就是声明依赖(Declaring Dependencies)模式: var myFunction = function () { //dependencies var event = YAHOO.util.Event, dom = YAH

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

沙盘模式可以弥补命名空间模式中的两项不足之处: 使用唯一全局对象作为程序的全局变量入口,使得无法在同一程序中使用两个不同版本的API,因此它们使用的是同一个唯一的全局对象名,如MYAPP: 较长的嵌套对象使得代码编写和解析都比较慢: 沙盘模式,正如其名字所说,提供了一个各类模块可以共同“游戏”的环境,模块之间和沙盘之间不会相互影响. 这种模式在YUI3中大量被使用.下面介绍一种沙盘模式的实现方式: 1. 全局的构造函数 在命名空间模式中只有一个全局对象:在沙盘模式中,唯一的是一个全局的构造函数:

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

首先,单例模式是对象的创建模式之一,此外还包括工厂模式.单例模式的三个特点: 1,该类只有一个实例 2,该类自行创建该实例(在该类内部创建自身的实例对象) 3,向整个系统公开这个实例接口 Java中大概是这个样子: class Singleton { //私有,静态的类自身实例 private static Singleton instance = new Singleton(); //私有的构造子(构造器,构造函数,构造方法) private Singleton(){} //公开,静态的工厂方

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

链式调用模式允许一个接一个地调用对象的方法.这种模式不考虑保存函数的返回值,所以整个调用可以在同一行内完成: myobj.method1("hello").method2().method3("world").method4(); 如果对象中有些方法不需要有返回值,就可以让它返回this引用,这个this引用就可以方便继续调用下一个方法: var obj = { value: 1, increment: function () { this.value += 1;

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

在支持“类”的面向对象语言中,静态成员指的是那些所有实例对象共有的类成员.静态成员实际是是“类”的成员,而非“对象”的成员.所以如果 MathUtils类中有个叫 max()的静态成员方法,那么调用这个方法的方式应该是这样的:MathUtils.max(3, 5). 1. 公有静态成员 JavaScript里并没有“类”的实际语言表示 ,所以也就没有静态成员的语义表示.但由于构造函数本身就是个对象,如果把构造函数看成“类”,那么它的成员就是可以通过“类”名(也就是构造函数)直接访问的“静态成员”

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

虽然许多编程语言提供了const关键字来支持常量的声明,但JavaScript里没有表示常量的语义.我们可以用全大写的方式来声明变量,表明它实际上是个常量: Math.PI; // 3.141592653589793 Math.SQRT2; // 1.4142135623730951 Number.MAX_VALUE; // 1.7976931348623157e+308 通常这种常量会用对象来包装起来:比如上面的Math.要实现程序里需要的常量,可以这样做: // constructor va

【javascript设计模式】构造器模式、模块模式、单例模式

构造器模式(Constructor) 构造器模式是学习js最早接触的一种,实现主要如下: 1 function myObject(name){ 2 this.name = name; 3 } 4 5 myObect.propotype = function sayName(){ 6 alert(this.name); 7 } 使用的时候需要new一个对象. 1 var myObj = new myObject('hello'); 2 myObj.sayName(); 模块模式(Module) 模