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 相关文章推荐
js实现ASP分页函数 HTML分页函数
Sep 22 Javascript
在JavaScript中获取请求的URL参数
Dec 22 Javascript
js在指定位置增加节点函数insertBefore()用法实例
Jan 12 Javascript
js实现有时间限制消失的图片方法
Feb 27 Javascript
js数组去重的方法汇总
Jul 29 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
Dec 24 Javascript
AngularJS基础 ng-dblclick 指令用法
Aug 01 Javascript
jQuery动态追加页面数据以及事件委托详解
May 06 jQuery
JavaScript体验异步更好的解决办法
Jan 08 Javascript
vue-swiper的使用教程
Aug 30 Javascript
Vue项目打包编译优化方案
Sep 16 Javascript
Vue中nprogress页面加载进度条的方法实现
Nov 13 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
php随机显示图片的简单示例
2014/02/15 PHP
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
php实现的简单检验登陆类
2015/06/18 PHP
简单谈谈php延迟静态绑定
2016/01/26 PHP
Laravel获取当前请求的控制器和方法以及中间件的例子
2019/10/11 PHP
extJs 常用到的增,删,改,查操作代码
2009/12/28 Javascript
js仿百度有啊通栏展示效果实现代码
2013/05/28 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
2014/02/22 Javascript
基于javascript实现checkbox复选框实例代码
2016/01/28 Javascript
bootstrap时间插件daterangepicker使用详解
2017/10/19 Javascript
通过一次报错详细谈谈Point事件
2018/05/17 Javascript
微信小程序开发的基本流程步骤
2019/01/31 Javascript
Layer+Echarts构建弹出层折线图的方法
2019/09/25 Javascript
JavaScript交换两个变量方法实例
2019/11/25 Javascript
基于JQuery和DWR实现异步数据传递
2020/10/16 jQuery
vue 数据操作相关总结
2020/12/17 Vue.js
javascript实现点击产生随机图形
2021/01/25 Javascript
[01:03:13]VG vs Pain 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
django模型中的字段和model名显示为中文小技巧分享
2014/11/18 Python
python批量提取word内信息
2015/08/09 Python
Linux-ubuntu16.04 Python3.5配置OpenCV3.2的方法
2018/04/02 Python
python tkinter canvas 显示图片的示例
2019/06/13 Python
使用phonegap进行提示操作的具体方法
2017/03/30 HTML / CSS
详解WebSocket跨域问题解决
2018/08/06 HTML / CSS
HTML5触摸事件(touchstart、touchmove和touchend)的实现
2020/05/08 HTML / CSS
贝嫂喜欢的婴儿品牌,个性化的婴儿礼物:My 1st Years
2017/11/19 全球购物
英国布鲁姆精品店:Bloom Boutique
2018/03/01 全球购物
三星英国官网:Samsung英国
2018/09/25 全球购物
shell程序中如何注释
2012/01/28 面试题
项目专员岗位职责
2013/12/04 职场文书
《母鸡》教学反思
2014/02/25 职场文书
民主评议党员总结
2014/10/20 职场文书
应届生求职自荐信范文
2015/03/04 职场文书
党支部对转正的意见
2015/06/02 职场文书
门卫管理制度范本
2015/08/05 职场文书
Spring boot实现上传文件到本地服务器
2022/08/14 Java/Android