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 相关文章推荐
基于prototype的validation.js发布2.3.4新版本,让你彻底脱离表单验证的烦恼
Dec 06 Javascript
基于jquery的滚动鼠标放大缩小图片效果
Oct 27 Javascript
Javascript合并表格中具有相同内容单元格示例
Aug 11 Javascript
jQuery插件jQuery-JSONP开发ajax调用使用注意事项
Nov 22 Javascript
js实现瀑布流的三种方式比较
Jun 28 Javascript
纯js实现画一棵树的示例
Sep 05 Javascript
vue.js 实现图片本地预览 裁剪 压缩 上传功能
Mar 01 Javascript
JavaScript实现微信红包算法及问题解决方法
Apr 26 Javascript
ajax与jsonp的区别及用法
Oct 16 Javascript
vue组件tabbar使用方法详解
Nov 06 Javascript
vue项目在线上服务器访问失败原因分析
Aug 14 Javascript
在vue项目中封装echarts的步骤
Dec 25 Vue.js
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基于mcrypt的加密解密实例
2014/10/27 PHP
搭建Vim为自定义的PHP开发工具的一些技巧
2015/12/11 PHP
php图片添加文字水印实现代码
2016/03/15 PHP
PHP模板引擎Smarty之配置文件在模板变量中的使用方法示例
2016/04/11 PHP
PHP实现的微信APP支付功能示例【基于TP5框架】
2019/09/16 PHP
Thinkphp 框架扩展之类库扩展操作详解
2020/04/23 PHP
两个DIV等高的JS的实现代码
2007/12/23 Javascript
jQuery dialog 异步调用ashx,webservice数据的代码
2010/08/03 Javascript
JS 数字转换研究总结
2013/12/26 Javascript
js判断ie版本号的简单实现代码
2014/03/05 Javascript
jquery获取tagName再进行判断
2014/05/29 Javascript
jquery解决客户端跨域访问问题
2015/01/06 Javascript
javascript bom是什么及bom和dom的区别
2015/11/26 Javascript
微信开发 微信授权详解
2016/10/21 Javascript
如何获取元素的最终background-color
2017/02/06 Javascript
JavaScript基本类型值-Number类型
2017/02/24 Javascript
jquery.rotate.js实现可选抽奖次数和中奖内容的转盘抽奖代码
2017/08/23 jQuery
深入理解vue中slot与slot-scope的具体使用
2018/01/26 Javascript
js实现微信聊天界面
2020/08/09 Javascript
[01:56]《DOTA2》中文配音CG
2013/04/22 DOTA
跟老齐学Python之变量和参数
2014/10/10 Python
Python+OpenCV让电脑帮你玩微信跳一跳
2018/01/04 Python
Python AES加密实例解析
2018/01/18 Python
python中seaborn包常用图形使用详解
2019/11/25 Python
Python实现多线程下载脚本的示例代码
2020/04/03 Python
Python描述数据结构学习之哈夫曼树篇
2020/09/07 Python
CSS3 优势以及网页设计师如何使用CSS3技术
2009/07/29 HTML / CSS
HTML5实现应用程序缓存(Application Cache)
2020/06/16 HTML / CSS
英国香水店:The Perfume Shop
2017/03/27 全球购物
什么情况下你必须要把一个类定义为abstract的
2013/01/06 面试题
干部竞争上岗演讲稿
2014/09/11 职场文书
公诉意见书范文
2015/06/05 职场文书
Python中使用subprocess库创建附加进程
2021/05/11 Python
Python matplotlib 利用随机函数生成变化图形
2022/04/26 Python
Java服务调用RestTemplate与HttpClient的使用详解
2022/06/21 Java/Android
CSS浮动引起的高度塌陷问题
2022/08/05 HTML / CSS