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 相关文章推荐
javascript while语句和do while语句的区别分析
Dec 08 Javascript
Jquery在IE7下无法使用 $.ajax解决方法
Nov 11 Javascript
javascript在子页面中函数无法调试问题解决方法
Jan 17 Javascript
关于jQuery判断元素是否存在的问题示例探讨
Jul 21 Javascript
jQuery中的read和JavaScript中的onload函数的区别
Aug 27 Javascript
JavaScript兼容性总结之获取非行间样式案例
Aug 07 Javascript
js本地图片预览实现代码
Oct 09 Javascript
canvas实现流星雨的背景效果
Jan 13 Javascript
PHP实现记录代码运行时间封装类实例教程
May 08 Javascript
vue实现购物车列表
Jun 30 Javascript
js实现页面导航层级指示效果
Aug 25 Javascript
OpenLayers3加载常用控件使用方法详解
Sep 25 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
mac下安装nginx和php
2013/11/04 PHP
php使用MySQL保存session会话的方法
2015/06/26 PHP
分享ThinkPHP3.2中关联查询解决思路
2015/09/20 PHP
PHP编写学校网站上新生注册登陆程序的实例分享
2016/03/21 PHP
解决php写入数据库乱码的问题
2019/09/17 PHP
将光标定位于输入框最右侧实现代码
2012/12/04 Javascript
jquery获取当前日期的方法
2015/01/14 Javascript
jquery制作LED 时钟特效
2015/02/01 Javascript
DOM操作一些常用的属性汇总
2015/03/13 Javascript
JS根据浏览器窗口大小实时动态改变网页文字大小的方法
2016/02/25 Javascript
jQuery选择器基础入门教程
2016/05/10 Javascript
node.js Sequelize实现单实例字段或批量自增、自减
2016/12/08 Javascript
javascript实现简单的可随机变色网页计算器示例
2016/12/30 Javascript
详解Vue-Cli 异步加载数据的一些注意点
2017/08/12 Javascript
使用VueRouter的addRoutes方法实现动态添加用户的权限路由
2019/06/03 Javascript
[02:19]2014DOTA2国际邀请赛 专访820少年们一起去追梦吧
2014/07/14 DOTA
[57:41]Secret vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
Python实现设置windows桌面壁纸代码分享
2015/03/28 Python
Python求两个文本文件以行为单位的交集、并集与差集的方法
2015/06/17 Python
python装饰器深入学习
2018/04/06 Python
python 计算两个列表的相关系数的实现
2019/08/29 Python
Python实现报警信息实时发送至邮箱功能(实例代码)
2019/11/11 Python
Python 在函数上添加包装器
2020/07/28 Python
浅谈HTML5 Web Worker的使用
2018/01/05 HTML / CSS
美国在线宠物商店:Chewy
2019/01/12 全球购物
美国智能家居专家:tink
2019/06/04 全球购物
PHP如何删除一个Cookie值
2012/11/15 面试题
内部类的定义、种类以及优点
2013/10/16 面试题
视光学专业毕业生推荐信
2013/10/28 职场文书
婚内房产协议书范本
2014/10/02 职场文书
教师党的群众路线教育实践活动个人整改方案
2014/10/31 职场文书
工会工作个人总结
2015/03/03 职场文书
停电通知范文
2015/04/16 职场文书
Pytorch 使用tensor特定条件判断索引
2021/04/08 Python
python Django框架快速入门教程(后台管理)
2021/07/21 Python
python playwrigh框架入门安装使用
2022/07/23 Python