2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > javaScript几种设计模式之一——单体模式

javaScript几种设计模式之一——单体模式

时间:2019-10-10 15:51:06

相关推荐

javaScript几种设计模式之一——单体模式

javaScript是一种弱类型、动态的、基于原型的语言,这种语言特性使得它非常容易、

甚至是普通的方式实现其中的一些模式。

单体模式的思想在于保证一个特定类仅有一个实例。这就意味着当您第二次使用同一个

类创建新对象的时候,应该得到与第一次所创建对象完全相同对象。

在javaScript中没有类,只有对象。当您创建一个新对象时,实际上没有其他对象与其

类似,因此新对象已经是单体了。使用对象字面量创建一个简单的对象也是一个单体的

例子。

var obj ={

myprop:’my value’

};

在javaScript中,对象之间永远不会完全相等,除非他们是同一个对象,因此即使创建

一个具有完全相同成员的同类对象,它也不会与第一个对象完全相同。

var obj2 = {

myprop:’mu value’

};

obj === obj2 //false

obj == obj2 //false

因此,可以认为每次在使用对象字面量创建对象的时候,实际上就正在创建一个单体,

并且并不涉及任何特殊语法。

javaScript中并没有类,因此对单体咬文嚼字的定义严格说来并没有意义。但是

javaScript中具有new语法可使用构造函数来创建对象,而且有时可能需要使用这种语法

的单体实现。这种思想在于当使用一个构造函数以new操作符来创建多个对象时,应该仅

获得指向完全相同的对象的新指针。

下面的代码显示了其预期行为

var uni = new Universe();

var uni2 = new Universe();

uni === uni2; //true

在上面的例子中,uni对象仅在第一次调用构造函数时被创建。在第二次及以后的创建时

将会返回同一个uni对象。这就是为什么uni===uni2,因为它们本质上是指向同一个对象

的两个引用。那么如何在javaScript中实现这种模式呢?

需要Universe构造函数缓存该对象实例this,以便当第二次调用该构造函数时能够创建并

返回同一个对象。有多种选择可以实现这一目标:

1.可以使用全局变量来存储该实例,但是并不推荐使用这种方法,因为在一般原则下,

全局变量有部分缺点。此外,任何人都能覆盖该全局变量。

可以在构造函数的静态属性中缓存该实例,javaScript中的函数也是对象,因此它们

也可以有属性。可以使用类似Universe.instance的属性并将实例缓存在该属性重工,这

是一种很好的实现方法,这种解决方案唯一的缺点在于instance属性是公开可访问的属

性,在外部代码中可能会修改该属性,以至于会丢失了该实例。

如例子:

function Universe(){

//判断是否有实例

if(typeof Universe.instance === ‘object’){

return Universe.instance;

}

//正常进行

this.start_time = 0;

this.bang = “Big”;

//缓存

Universe.instance = this;

}

//

var uni = new Universe();

var uni2 = new Universe();

uni === uni2; //true

这种方法是一个非常直接的解决方法,其唯一的缺点在于其instance属性是公开的,虽

然其他代码不太可能会无意中修改该属性,但是仍然存在这种可能性。

3.可以将该实例包装在闭包中。这样可以保证该实例的私有属性并且保证该实例不会被

构造函数之外的代码所修改,缺点就是带来了额外的闭包开销。

如下面例子:

function Universe(){

//缓存实例

var instance = this;

//正常进行

this.start_time=0;

this.bang = “big”;

//重写该构造函数

Universe = function(){

return instance;

};

}

var uni = new Universe();

var uni2 = new Universe();

uni === uni2; //true

当第一次调用原始构造函数时,它像往常一样返回this,然后,在第二次、第三次调用

时,将执行重写构造函数。该重写构造函数通过闭包访问了私有instance 变量,并且仅

简单返回了该instance.在重写构造函数会丢失所有在初始定义和重定义时刻之间添加到

它里面的属性。在这列的特定情况下,任何添加到universe的原型中对象都不会存在指

向由原始实现所创建实例的活动链接。

另外一种方法是将构造函数和实例包装在即时函数中。在第一次调用构造函数时,它会

创建一个对象,并且似的私有instance指向该对象,从第二次调用之后,该构造函数仅

返回该私有变量,通过这个新的实现方式,前面所有代码片段的测试也都会按照预期运

行。

var Universe;

(function (){

var instance;

Universe = function Unvierse(){

if(instance){

return instance;

}

instance = this;

//所有功能

this.start_time = 0;

this.bang = “Big”;

};

}());

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。