职业IT人-IT人生活圈

 找回密码
 成为会员
搜索
查看: 380|回复: 1

ExtJS设计模式-模块模式(Module Pattern)

[复制链接]
江波 发表于 2011-8-24 10:23 | 显示全部楼层 |阅读模式
在《JavaScri......
推荐链接 20-30......


在《JavaScript: The Definitive Guide, 5th Edition》一书的8.8章节其中有一段这样的描述:

When you define a nested function, however, the scope chain includes the containing function. This means that nested functions can access all of the arguments and local variables of the containing function.

这句话的主要意思可以理解为:
当你在js中定义一个内部函数时,此内部函数的作用域链将此内部函数包含的所有函数都include到了其中。这就意味着内部函数可以访问所有的包含在其中的函数的参数和本地变量。

在ExtJS的设计中大量利用了这个特点设计代码,获得的最大好处有两点:

1、实现封装

这种写法保证了此方法中定义的内部函数(nested function)与本地变量(local variables)不能被外部访问,同时只允许特权(公有)方法访问这些内部函数或者变量。作用类似于javabean的private成员以及getXXX方法。

2、性能提升(单例模式)-通过模块模式实现

模块模式与单例模式的关系是什么?在提到这个之前不得不提到javascript的单例模式(Singleton)。在javascript中,单例(Singleton)就是指只有一个实例的对象,而不需要用new关键字去创建一个对象实例。单例其实有点类似于java里面的静态类。在javascript中,是以对象字面量的方式来创建单例对象的,也就是以花括号包裹起来的键值对的JSON形式来创建的。例如:
Javascript代码  
var singletonObj={   
    field1:'aaa',   
    methodA:function(){   
        //code...   
    }   
};   

var singletonObj={
    field1:'aaa',
    methodA:function(){
        //code...
    }
};


单例模式的目的就是尽可能少的创建对象,最终目的其实就是性能的提升。这点是程序员都清楚,无须多言。

模块模式则是用来对单例对象进行封装,从而能增强单例的可访问性。
以模块模式定义的内部函数(nested function)与变量(local variables)只有单例对象本身的特权(公有)
方法可以访问到,其他外部的任何对象都不可以。
其语法形式如下:
Javascript代码  
Util = function() {   
    // private   
    var A = 1;   
    var C = 2;   
    // private   
    function methodA() {   
        // 打印本地变量   
        alert("A="+A);   
    }   
    function methodC(argC) {   
        // 打印参数   
        alert("argC=" + argC);   
    }   
  
    return {   
             B : 3,   
        methodB : function() {   
            methodA();   
        },   
        methodD : function() {   
            //打印本地变量   
            alert(C);   
            //将本地变量作为参数使用   
            methodC(C);   
        }   
    }   
}(); //匿名函数立即执行,并且返回  

Util = function() {
        // private
        var A = 1;
        var C = 2;
        // private
        function methodA() {
                // 打印本地变量
                alert("A="+A);
        }
        function methodC(argC) {
                // 打印参数
                alert("argC=" + argC);
        }

        return {
                 B : 3,
                methodB : function() {
                        methodA();
                },
                methodD : function() {
                        //打印本地变量
                        alert(C);
                        //将本地变量作为参数使用
                        methodC(C);
                }
        }
}(); //匿名函数立即执行,并且返回


上面的代码中,我们创建了一个匿名函数并赋值给变量Util,然后立即调用这个函数返回可以公开的公有方法和属性的对象实例。在匿名函数内部定义了本地(私有)变量A,C,内部(私有)函数methodA(),methodC()。然后将一个对象实例作为函数值返回,这样返回的对象中只包含可以公开的属性(指变量B)和方法(指函数methodB(),methodD())。

单例对象中公有属性和公有方法的调用与一般对象的属性和方法调用一样,使用点表示法或者方括号语法来调用单例对象的公有成员。

让我们通过以下代码,进一步验证我们的想法。

执行以下代码,会得到TypeError: Util.methodA is not a function
Javascript代码  
//内部函数不能被访问   
Util.methodA();  

//内部函数不能被访问
Util.methodA();


执行以下代码,会得到ReferenceError: A is not defined
Javascript代码  
//本地变量不能被访问   
alert(A);   

//本地变量不能被访问
alert(A);


执行以下代码,得到1
Javascript代码  
//单例模式通过公有方法可以访问内部函数,进而访问本地变量   
Util.methodB();  

//单例模式通过公有方法可以访问内部函数,进而访问本地变量
Util.methodB();


执行以下代码,得到2 C=2 argC=2
Javascript代码  
//单例模式通过公有方法可以访问内部函数,进而访问本地变量,以及内部函数参数   
Util.methodD();  

//单例模式通过公有方法可以访问内部函数,进而访问本地变量,以及内部函数参数
Util.methodD();


执行以下代码,得到ReferenceError: B is not defined
Javascript代码  
//公有变量不能直接访问。   
alert(B);  

//公有变量不能直接访问。
alert(B);


执行以下代码,得到3
Javascript代码  
//公有变量可以通过单例模式访问   
alert(Util.B);  

//公有变量可以通过单例模式访问
alert(Util.B);




所以,模块模式的适用场景:需要对单例进行一些初始化,又需要对私有变量进行封装时。

参考资料链接:
http://www.cnblogs.com/fengmiaosen/archive/2011/01/11/1933219.html

参考文档:
<JavaScript: The Definitive Guide, 5th Edition> By David Flanagan

叫我小乖 发表于 2011-8-24 10:23 | 显示全部楼层
推荐链接
20-30万急聘多名天才Java/MTA软件工程师

见证又一个准百万富翁的诞生!
3G培训就业月薪平均7K+,不3K就业不花一分钱!

您需要登录后才可以回帖 登录 | 成为会员

本版积分规则

QQ|手机版|小黑屋|网站帮助|职业IT人-IT人生活圈 ( 粤ICP备12053935号-1 )|网站地图
本站文章版权归原发布者及原出处所有。内容为作者个人观点,并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是信息平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽造成漏登,请及时联系我们,我们将根据著作权人的要求立即更正或者删除有关内容。

GMT+8, 2024-5-9 23:04 , Processed in 0.130709 second(s), 20 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表