博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
单例模式
阅读量:6829 次
发布时间:2019-06-26

本文共 3298 字,大约阅读时间需要 10 分钟。

单例模式

定义: 保证一个类只有一个实例,并提供一个访问它的全局访问点。

var single = function(name){    this.name = name;    this.instance = null;}single.prototype.getName = function(){    alert(this.name)}single.getInstance = function(name){    if(!this.instance){        this.instance = new single(name)    }    return this.instance}var a = new single.getInstance('ffff');var a2 = new single.getInstance('zzzz');// a == a2  => true

或者

var single = function(name){    this.name = name;}single.prototype.getName = function(){    console.log(this.name)}single.getInstance = (function(){    var instance = null;    return function(name){        if(!instance){            instance = new single(name)        }        return isntance    }})()
  • 使用single类时,我们必须知道它是一个单例类,跟以往new出一个新对象的方式不同,这里要使用single.getInstance来获取对象。

透明的单例

var createDiv = (function(){    var instance = null;    var createDiv = function(html){        if(instance) return instance        this.html = html;        this.init()        return instance = this;    }     createDiv.prototype.init = function(){        var div = document.createElement('div')        div.innerHTML = this.html;        document.body.appendChild(div)    }    return createDiv})()
  • 这个透明类的单例,我们使用了自执行函数和闭包,并且让这个匿名函数返回真正的single构造方法,增加了代码的复杂度,读起来需要一定的时间来理解

  • 构造函数的作用,实际上做了两件事,创建对象和执行初始化init方法,第二保证了只有一个对象

用代理来实现单例模式

var createDiv = function(html){    this.html = html;    this.init();}createDiv.prototype.init = function(){    var div = document.createElement('div');    div.innerHTML = this.html;    document.body.appendChild(div);}

引入代理类

var proxySingle = (function(){    var instance;    return function(html){        if(!instance){            instance = new createDiv(html)        }        return instance    }})()
  • 通过代理模式完成的代码,我把管理单例的逻辑移到了proxySingle里,这样createDiv就变成了一个普通的类

这个例子是缓存代理的应用之一。

惰性单例

  • 惰性单例指的是在需要的时候才创建对象实例。

这种技术在实际开发中非常有用。

在网站首页,有个登陆按钮,点击登录 弹出登录框。很明显这个登录框在页面中是唯一的,不会也不可能出现两个登陆框。

首先我们可以页面加载完成时就加载这个登录框,此时这个登录框出于隐藏状态。

但是如果我进入页面只是想看看,不想进行一些需要登陆的业务操作,此时登陆框的dom节点存在是没有意义的,是一种浪费。
此时,单例模式就更实用了

//dom//jsvar createLogin = (function(){    var div;    return function(){        if(!div){        div= document.createElement('div');        div.innerHTML = "i'm login form";        div.display.style="none";        document.body.appendChild(div);        return div        }    }    })()document.getElementById('login').onClick = function(){    var loginDom = createLogin();    loginDom.display.style ='block'}

通用惰性单例

我们参考上边的代码,如果需要在创建一个iframe单例,或者其他标签,难道需要把上边的函数重新copy一份修改.单例的逻辑可以抽象出来,并且始终不变的,可以理解为

var instance;if(!instance){   instance = xxx操作}return instance

我们将管理单例的逻辑抽象封装起来getInstance

var getInstance = function(fn){    var instance;    return function(){        return instance || (result = fn.apply(this,arguments))    }}//创建登陆var createLogin = getInstance(function(){    var div = document.createElement('div');    div.innerHTML = '我是的登陆';    div.style.display = 'none';    document.body.appenChild(div);    return div})//$('#login').on('click',function(){    var login = createLogin();    $(login).show()})//创建scriptvar createScript = getInstance(function(){    var script = document.createElement('script');    document.appendChild(script)    return script})$('#loadScript').on('click',function(){    var script = createScript();    $(script).show();})

将创建实例对象的职责和管理单例的职责分别放置在两个方法里,这两个方法独立,不会互相影响。

转载地址:http://doykl.baihongyu.com/

你可能感兴趣的文章
新东方雅思词汇---8.3、apt
查看>>
Visual Studio 2015安装过程卡住,解决办法
查看>>
src与href的区别
查看>>
Python小练习更改版(更改一部分代码,与错误)
查看>>
Jenkins持续集成学习-搭建jenkins问题汇总
查看>>
公众号python
查看>>
基于OWIN的WEB API承载
查看>>
Linux-常见服务配置(软件、服务、配置文件)
查看>>
XML和JSON的区别
查看>>
javascript中的this指向问题总结
查看>>
git强制放弃本地更改
查看>>
mapreduce中一个map多个输入路径
查看>>
HBase 多级索引
查看>>
虚拟机Ubuntu16.04安装lrzsz
查看>>
树状数组总结
查看>>
STL vector练习
查看>>
【转载】复数基础知识
查看>>
kali网络环境配置
查看>>
VC++6.0 IDE的工程用Code::Blocks来打开、编译、调试终极配置方案
查看>>
spring mvc 重定向,转发和传参
查看>>