位置:海鸟网 > IT > JavaScript >

javascript设计模式之单体模式

单体是一个用来划分命名空间并将一批相关的属性和方法组织在一起的对象,如果他可以被实例化,那么他只能被实例化一次。

单体模式是里面最基本但也是最有用的模式之一。

特点:

1.       可以来划分命名空间,从而清除全局变量所带来的危险。

2.       利用分支技术来来封装浏览器之间的差异。

3.       可以把代码组织的更为一体,便于阅读和维护。

单体的基本结构(正确写法):

/*Basic Singleton*/
var Singleton = {

         attribute1:true,

         attribute2:10,

         method1:function(){},

     method2:function(){}

};

1划分命名空间:

 1 var box = {
 2         width:0,
 3         height:0,
 4         getArea:function(){
 5             return this.width*this.height;//js中对象成的访问必须是显示的,即this是不能省略的
 6         },
 7         init:function(w,h){
 8         //    width = w;
 9         //    height = h;这种方式相当于定义了两个全局变量,(没加var声明的变量为全局变量)
10         //    并不是对对象width和height的赋值
11         //下面是正确的
12             this.width = w;
13             this.height = h;
14         }
15     }//box划分了一个命名空间,命名空间里的变量只在空间里有效
16 

上面的单体中的所有的成员以及方法都是公有的(public),也就是在单体的外部可以对他们进行任意的改动,那为什么说单体提供了一个命名空间呢?

我们继续:

 1 var box = {
 2         width:0,
 3         height:0,//单体的变量
 4         getArea:function(){
 5             return width*height;//中的,width,height其实并不是单体的变量,而是在init中定义的全局变量
 6         }
 7         init:function(w,h){
 8             width = w;
 9             height = h;
10         }
11     }//init中width,height其实并不是单体的变量
12 window.onload = function(){
13         var init = box.getArea();
14     alert(init);
15 }

由于没有对init中的width,height进行初始化,所以会报错,这样改一下:

 1 var box = {
 2         width:0,
 3         height:0,
 4         getArea:function(){
 5             return width*height;
 6         },
 7         init:function(w,h){
 8             width = w;
 9             height = h;
10         }
11     }
12 window.onload = function(){
13         width = 0;
14         height = 0;
15         //or box.init(0,0);
16         var init = box.getArea();
17     alert(init);
18 }

发现可以了,由于init和 getArea所用的width和height并不是归单体所有的变量,而是一个全局变量,所以我们可以在单体外面进行随意调用而不受影响

如果我们这样写一下就更明白了:

 1 var box = {
 2         width:0,
 3         height:0,
 4         getArea:function(){
 5             return width*height;//js中对象成的访问必须是显示的,即this是不能省略的
 6         },
 7         init:function(w,h){
 8             width = w;
 9             height = h;
10         }
11     }//这里的width,height其实并不是单体的对象
12 window.onload = function(){
13         width = 0;
14         height = 0;
15         var width = box.getArea();
16     alert(width);
17 }

这样写又会报错了,可见我们以上的方式对于全局变量并没有建立起一个命名空间,全局变量为我们带来了危险。所以最上面的写法是对的,我们来验证一下:

 1 var box = {
 2         width:2,
 3         height:2,
 4         getArea:function(){
 5             return this.width*this.height;//js中对象成的访问必须是显示的,即this是不能省略的
 6         },
 7         init:function(w,h){
 8             this.width = w;
 9             this.height = h;
10         }
11     }
12 window.onload = function(){
13         width = 0;
14         height = 0;
15         var width = box.getArea();
16     alert(width);
17 }

可见在window.onload中的width 和height已经没有干扰了,因为单体为单体中的width和height建立了一个命名空间。