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管理作用域的问题
Apr 10 Javascript
文字溢出实现溢出的部分再放入一个新生成的div中具体代码
May 17 Javascript
javascript控制Div层透明属性由浅变深由深变浅逐渐显示
Nov 12 Javascript
《JavaScript DOM 编程艺术》读书笔记之JavaScript 图片库
Jan 09 Javascript
JavaScript判断页面加载完之后再执行预定函数的技巧
May 17 Javascript
浅谈Sublime Text 3运行JavaScript控制台
Jun 06 Javascript
详解js中Json的语法与格式
Nov 22 Javascript
jQuery实现花式轮播之圣诞节礼物传送效果
Dec 25 Javascript
canvas绘制多边形
Feb 24 Javascript
在ES5与ES6环境下处理函数默认参数的实现方法
May 13 Javascript
用vue快速开发app的脚手架工具
Jun 11 Javascript
vue实现用户长时间不操作自动退出登录功能的实现代码
Jul 23 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
smtp邮件发送一例
2006/10/09 PHP
PHP 简单数组排序实现代码
2009/08/05 PHP
php中长文章分页显示实现代码
2012/09/29 PHP
yii实现级联下拉菜单的方法
2014/07/31 PHP
destoon实现不同会员组公司名称显示不同的颜色的方法
2014/08/22 PHP
Linux中为php配置伪静态
2014/12/17 PHP
php+croppic.js实现剪切上传图片功能
2018/08/14 PHP
Yii2框架控制器、路由、Url生成操作示例
2019/05/27 PHP
Firefox和IE浏览器兼容JS脚本写法小结
2008/07/07 Javascript
多个表单中如何获得这个文件上传的网址实现js代码
2013/03/25 Javascript
js单例模式详解实例
2013/11/21 Javascript
node.js中的fs.fsyncSync方法使用说明
2014/12/15 Javascript
纯JS实现本地图片预览的方法
2015/07/31 Javascript
AngularJS 基础ng-class-even指令用法
2016/08/01 Javascript
用headjs来管理和加载js 提高网站加载速度
2016/11/29 Javascript
nodejs前端自动化构建环境的搭建
2017/07/26 NodeJs
详解vue引入子组件方法
2019/02/12 Javascript
在element-ui的select下拉框加上滚动加载
2019/04/18 Javascript
基于elementUI使用v-model实现经纬度输入的vue组件
2019/05/12 Javascript
vue实现轮播图帧率播放
2021/01/26 Vue.js
[43:14]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第二场 8.21
2018/08/22 DOTA
python第三方库学习笔记
2020/02/07 Python
PyCharm取消波浪线、下划线和中划线的实现
2020/03/03 Python
Pyecharts地图显示不完成问题解决方案
2020/05/11 Python
Python3+selenium配置常见报错解决方案
2020/08/28 Python
python 获取谷歌浏览器保存的密码
2021/01/06 Python
利用纯CSS3实现动态的自行车特效源码
2017/01/20 HTML / CSS
职工代表大会主持词
2014/04/01 职场文书
《大自然的语言》教学反思
2014/04/08 职场文书
物业管理工作方案
2014/05/10 职场文书
团党委领导干部党的群众路线教育实践活动个人对照检查材料思想汇
2014/10/05 职场文书
优秀团员个人总结
2015/02/26 职场文书
建筑质检员岗位职责
2015/04/08 职场文书
2015年财务科工作总结范文
2015/05/13 职场文书
旷工检讨书大全
2015/08/15 职场文书
2019运动会广播加油稿汇总
2019/08/21 职场文书