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 相关文章推荐
html下载本地
Jun 19 Javascript
jquery实现智能感知连接外网搜索
May 21 Javascript
JavaScript表单通过正则表达式验证电话号码
Mar 14 Javascript
IE及IE6浏览器中判断JS文件加载成功失败的方法
Feb 18 Javascript
js实现鼠标点击文本框自动选中内容的方法
Aug 20 Javascript
使用ionic切换页面卡顿的解决方法
Dec 16 Javascript
javascript 正则表达式分组、断言详解
Apr 20 Javascript
jquery一键控制checkbox全选、反选或全不选
Oct 16 jQuery
老生常谈JS中的继承及实现代码
Jul 06 Javascript
vue代理和跨域问题的解决
Jul 18 Javascript
解决vue单页路由跳转后scrollTop的问题
Sep 03 Javascript
在vue中使用vuex,修改state的值示例
Nov 08 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
风味层面去分析咖啡油脂
2021/03/03 咖啡文化
php遍历解析xml字符串的方法
2016/05/05 PHP
PHP编译configure时常见错误的总结
2017/08/17 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
php使用curl获取header检测开启GZip压缩的方法
2018/08/15 PHP
PHP sdk文档处理常用代码示例解析
2020/12/09 PHP
Nigma vs Alliance BO5 第三场2.14
2021/03/10 DOTA
Ajax搜索结果页面下方的分页按钮的生成
2012/04/05 Javascript
键盘KeyCode值列表汇总
2013/11/26 Javascript
用简洁的jQuery方法toggleClass实现隔行换色
2014/10/22 Javascript
jQuery鼠标经过方形图片切换成圆边效果代码分享
2015/08/20 Javascript
JavaScript遍历求解数独问题的主要思路小结
2016/06/12 Javascript
AngularJS+Bootstrap实现多文件上传与管理
2016/11/08 Javascript
微信页面倒计时代码(解决safari不兼容date的问题)
2016/12/13 Javascript
微信小程序 仿猫眼实现实例代码
2017/03/14 Javascript
利用types增强vscode中js代码提示功能详解
2017/07/07 Javascript
Vue-cli配置打包文件本地使用的教程图解
2018/08/02 Javascript
koa-passport实现本地验证的方法示例
2020/02/20 Javascript
[05:01]3.19DOTA2发布会 我们都是刀塔人
2014/03/25 DOTA
[03:08]迎霜节狂欢!2018年迎霜节珍藏Ⅰ一览
2018/12/25 DOTA
[52:26]完美世界DOTA2联赛决赛 FTD vs Phoenix 第一场 11.08
2020/11/11 DOTA
python 列表转为字典的两个小方法(小结)
2019/06/28 Python
在Python中获取操作系统的进程信息
2019/08/27 Python
windows 10 设定计划任务自动执行 python 脚本的方法
2019/09/11 Python
Python3安装pip工具的详细步骤
2019/10/14 Python
python opencv图片编码为h264文件的实例
2019/12/12 Python
使用 PyTorch 实现 MLP 并在 MNIST 数据集上验证方式
2020/01/08 Python
Europcar西班牙:全球汽车租赁领域的领导者
2018/09/17 全球购物
小学班主任评语大全
2014/04/23 职场文书
小学生迎国庆演讲稿
2014/09/05 职场文书
承诺书范本
2015/01/21 职场文书
2015年乡镇信访工作总结
2015/04/07 职场文书
狂人日记读书笔记
2015/06/30 职场文书
《中华上下五千年》读后感3篇
2019/11/29 职场文书
centos8安装MongoDB的详细过程
2021/10/24 MongoDB
教你win10系统中APPCRASH事件问题解决方法
2022/07/15 数码科技