JavaScript实现单例模式实例分享


Posted in Javascript onDecember 22, 2017

传统单例模式

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

实现单例核心思想

无非是用一个变量来标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时,直接返回之前创建的对象,接下来我们用JavaScript来强行实现这个思路,请看代码:

var Singleton = function( name ){
  this.name = name;
};
Singleton.prototype.getName = function(){ alert ( this.name );
};
Singleton.getInstance = (function(){ 
var instance = null;

return function( name ){





if ( !instance ){






instance = new Singleton( name );





}




return instance;


 }
})();

我们通过Singleton.getInstance来获取Singleton类的唯一对象,这样确实是没问题的,但是js本身是没有类这种概念的,所以我们强行用传统单例思想来实现是没有任何意义的,这样的代码又臭又长(其实是我自己看着不舒服嘻嘻嘻)。下面我们使用JavaScript的闭包来实现一个单例,请看代码:

var CreateDiv = (function(){ 

var instance;



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; })();
var a = new CreateDiv( 'sven1' ); var b = new CreateDiv( 'sven2' );
alert ( a === b ); // true

可以看到,这样我们确实用闭包来实现了一个单例,但这个代码还是高度耦合的,CreateDiv的构造函数实际上负责了两件事情。第一是创建对象和执行初始化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 ProxySingletonCreateDiv = (function () {
    var instance;
    return function (html) {
      if (!instance) {
        instance = new CreateDiv(html);
      }
      return instance;
    }
  })();
  var a = new ProxySingletonCreateDiv('sven1');
  var b = new ProxySingletonCreateDiv('sven2');
  alert(a === b); //true

可以看到,现在我们的构造函数CreateDiv现在只负责构造对象,至于是返回现有对象还是构造新的对象并返回,这件事我们交给了代理类proxySingletonCreateDiv来处理,这样的代码看着才舒(zhuang)服(bi)嘛!

最后贴一个高度抽象的单例模式代码,惰性单例的精髓!

//单例模式抽象,分离创建对象的函数和判断对象是否已经创建
  var getSingle = function (fn) {
    var result;
    return function () {
      return result || ( result = fn.apply(this, arguments) );
    }
  };

形参fn是我们的构造函数,我们只要传入任何自己需要的构造函数,就能生成一个新的惰性单例。比如说传入创建一个女朋友的构造函数,并且调用getSingle(),就能生成一个新的女朋友。如果以后再调getSingle(),也只会返回刚才创建的那个女朋友。至于新女朋友——不存在的。

单例常用场景

只需要生成一个唯一对象的时候,比如说页面登录框,只可能有一个登录框,那么你就可以用单例的思想去实现他,当然你不用单例的思想实现也行,那带来的结果可能就是你每次要显示登陆框的时候都要重新生成一个登陆框并显示(耗费性能),或者是不小心显示出了两个登录框。

以上就是我们给大家分享的关于JS实现单例模式的相关学习的心得,感谢大家对三水点靠木的支持。

Javascript 相关文章推荐
使用jscript实现二进制读写脚本代码
Jun 09 Javascript
JS.findElementById()使用介绍
Sep 21 Javascript
使用js判断控件是否获得焦点
Jan 03 Javascript
JavaScript中的null和undefined区别介绍
Jan 01 Javascript
jQuery实现行文字链接提示效果的方法
Mar 10 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
Oct 08 Javascript
基于jQuery实现照片墙自动播放特效
Jan 12 Javascript
Node.js pipe实现源码解析
Aug 12 Javascript
Vue cli 引入第三方JS和CSS的常用方法分享
Jan 20 Javascript
小白教程|一小时上手最流行的前端框架vue(推荐)
Apr 10 Javascript
express框架下使用session的方法
Jul 31 Javascript
探究一道价值25k的蚂蚁金服异步串行面试题
Aug 21 Javascript
vue使用axios时关于this的指向问题详解
Dec 22 #Javascript
Javascript中JSON数据分组优化实践及JS操作JSON总结
Dec 22 #Javascript
vue init失败简单解决方法(终极版)
Dec 22 #Javascript
使用axios实现上传图片进度条功能
Dec 21 #Javascript
详解使用webpack构建多页面应用
Dec 21 #Javascript
使用ajax的post同步执行(实现方法)
Dec 21 #Javascript
jQuery Validate插件ajax方式验证输入值的实例
Dec 21 #jQuery
You might like
syphon 虹吸式咖啡冲泡冲煮倒水的得与失
2021/03/03 冲泡冲煮
一些PHP写的小东西
2006/12/06 PHP
php教程之魔术方法的使用示例(php魔术函数)
2014/02/12 PHP
PHP自定义函数获取汉字首字母的方法
2016/12/01 PHP
PHP中mysqli_get_server_version()的实例用法
2020/02/03 PHP
如何在PHP环境中使用ProtoBuf数据格式
2020/06/19 PHP
创建一个复制UBB软件信息的链接或按钮的js代码
2008/01/06 Javascript
Javascript 生成指定范围数值随机数
2009/01/09 Javascript
jQuery 学习第五课 Ajax 使用说明
2010/05/17 Javascript
JavaScript charCodeAt方法入门实例(用于取得指定位置字符的Unicode编码)
2014/10/17 Javascript
JavaScript function函数种类详解
2016/02/22 Javascript
JS实现的自定义水平滚动字体插件完整实例
2016/06/17 Javascript
微信小程序 教程之事件
2016/10/18 Javascript
Bootstrap基本样式学习笔记之表单(3)
2016/12/07 Javascript
BootStrap 获得轮播中的索引和当前活动的焦点对象
2017/05/11 Javascript
Vue中定义全局变量与常量的各种方式详解
2017/08/23 Javascript
AngularJS实现的select二级联动下拉菜单功能示例
2017/10/25 Javascript
Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)
2018/02/08 Javascript
JS实现的贪吃蛇游戏完整实例
2019/01/18 Javascript
解决Mint-ui 框架Popup和Datetime Picker组件滚动穿透的问题
2020/11/04 Javascript
压缩包密码破解示例分享(类似典破解)
2014/01/17 Python
快速入手Python字符编码
2016/08/03 Python
浅析python中SQLAlchemy排序的一个坑
2017/02/24 Python
利用python实现微信头像加红色数字功能
2018/03/26 Python
使用canvas生成含有微信头像的邀请海报没有微信头像问题
2019/10/29 HTML / CSS
美国领先的机场停车聚合商:Airport Parking Reservations
2020/02/28 全球购物
旅游与环境专业求职信
2014/06/05 职场文书
乡镇精神文明建设汇报材料
2014/08/15 职场文书
课堂打架检讨书200字
2014/11/21 职场文书
孝老爱亲事迹材料
2014/12/24 职场文书
总账会计岗位职责
2015/04/02 职场文书
医院病假条范文
2015/08/17 职场文书
运动会广播稿50字
2015/08/19 职场文书
2019学子的答谢词范本!
2019/07/05 职场文书
DIY胆机必读:各国电子管评价
2022/04/06 无线电
利用nginx搭建RTMP视频点播、直播、HLS服务器
2022/05/25 Servers