JavaScript设计模式-单例模式

在软件开发过程中,我们往往对于一些资源,只需要全局性的一个。比如说唯一的一个线程池,浏览器窗口中唯一的一个window对象等等。这时候,我们需要一类只能有一个实例,并提供一个访问它的全局访问点,这就是单例模式的概念。

实现单例模式最简单的,就是设置一个标志,又这个标志来判断是否已经创建了该类。

var singleton = function( name ){
    this.name = name;
    this.instance = null;
}

singleton.prototype.sayName = function(){
    console.log(this.name);
}
singleton.getInstance = function(name){
    if(!this.instance)
    {
        this.instance = new singleton(name);
    }
    return this.instance;
}

//测试
var ins1 = singleton.getInstance('liu');
var ins2 = singleton.getInstance('yang');
ins1 == ins2    //返回为true;并且此时调ins2.sayName打印的是'liu'

这就是一个单例,但是这种实现方式是有缺点的,必须规定创建类用singleton.getInstance方法才可以,否则这个类我们照样也可以用new来创建,这时候这就不是一个单例的模式了。

为了可以用new关键字来创建单例,跟普通实习的创建方式相同,我们可以改写成下面这样:

var singleton = (function( name ){
    var instance;
    var create = function(name){
        if(instance)
        {
            return instance;
        }
        this.name = name;
        return instance=this;
    }
    return create;
})();

var a = new singleton('liu');
var b = new singleton('yang');
a == b;    //返回true

实际创建的是create这个类,并且只会实例一次。

最后来写一个通用的单例,比如我们有些时候想把一个对象作为普通对象去使用,有时候又想作为单例去使用,而且我一个单例的函数就可以生成很多种不同类型的单例,这时候可以将实现单例时共有的部分抽出来,而将一些个性作为参数传到函数里面。比如下面这种方式:

function Poll(){
    this.name='线程池';
    return this;
}
function Global(){
    this.name = 'window对象';
    return this;
}
var single = function(fn){
    var instance;
    return function(){
        return instance || (instance=fn.apply(this, arguments))
    }
}
//创建线程池单例的函数
var pollInstance = single(Poll);

//创建Window对象单例的函数
var winInstance = single(Global);

上面两个函数其实是相同的函数,不同的是传的参数不同,同时这里利用了闭包,即每次运行pollInstance之后的instance变量是不会从内存中消失的。
单例模式有很多应用,比如我们给某个DOM添加点击事件,添加一次就可以了,这时候可以利用一个单例模式;或者我们做一个轮播图,只需要整个div中有一个img元素,每次去换src就可以,这时候就可以把创建img元素加到div中的操作用单例模式来实现等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值