首页 > 语言 > JavaScript > 正文

JavaScript实现设计模式中的单例模式的一些技巧总结

2024-05-06 14:58:12
字体:
来源:转载
供稿:网友

一、使用全局变量保存单例

这是最简单的实现方法

function Person(){   this.createTime=new Date(); } var instance=new Person(); function getInstance(){   return instance; } 

加载该js时就创建一个Person对象,保存到instance全局变量中,每次使用都取这个对象。如果一次都没使用,那么创建的这个对象则浪费了,我们可以优化一下,

var instance function getInstance(){   if(!instance){     instance=new Person();   }   return instance; } 

这样,第一次使用时才创建对象。
这个方法的缺点是,instance是全局的变量,在多人合作或者开发周期比较长的情况下,很难保证instance不会被其它代码修改或覆盖,很可能到调用的时候,发现instance根本就不是Person对象。
我们考虑下使用闭包来封装起instance,使它不再是全局变量就可以解决这个问题了

二、闭包创建对象

var getInstance(){ var instance; return function(){     if(!instance){       instance=new Person();     }     return instance;   } }(); 

这样,instance就被封装起来了,不用担心被修改了。
现在通过getInstance()函数可以获得单例了。新的问题,如果我通过new Person()来创建对象,获得的还是多个对象,javascript又不可以像java一样把构造器私有化。那怎么样可以让多次new出来的对象都是一个实例呢?

三、构造函数的静态属性缓存实例

先看代码

function Person(){   //如果已经缓存了实例,则直接返回缓存的实例   if(typeof Person.instance==='object'){     return Person.instance;   }   this.createTime=new Date();   //缓存实例   Person.instance=this;   return this; } 

从代码可以看到,第一次new时,if的条件返回false,会往下走,初始化对象,然后保存对象到Person.instance这个静态属性中。
第二次new 时,if的条件返回true,直接返回Person.instance,不会再往下运行初始化的代码。所以不管new几次,返回的都是第一次创建的对象。

这个方法的缺点和方法一的缺点一样,Person.instance也是公开属性,有可能会被修改。

我们参考方法二,使用闭包来封装一个,也许就能解决该问题了

四、重写构造函数

这个方法要使用闭包,但不能像方法二那么简单,我们需要重写构造函数。

function Person(){   //缓存实例   var instance=this;   this.createTime=new Date();   //重写构造函数   Person=function(){     return instance;   } } 

第一次new 时,调用原始构造函数先缓存该实例,然后再初始化,同时,重写该构造函数。以后再new 时,永远调用不到原始的构造函数了,只能调用到重写后的构造函数,而这个函数总是返回缓存的instance.

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

图片精选