轻松掌握JavaScript单例模式


Posted in Javascript onAugust 25, 2016

定义:保证一个对象(类)仅有一个实例,并提供一个访问它的全局访问点;
实现原理:利用闭包来保持对一个局部变量的引用,这个变量保存着首次创建的唯一的实例; 
主要用于:全局缓存、登录浮窗等只需要唯一一个实例的时候; 

一. 为一个非单例模式对象(如:Demo)实现单例模式的方法:
 给Demo添加一个静态方法来实现单例:

Demo.getSingle = (function(){
  var demo = null;
  return function(name){
    if(!demo){
      demo = new Demo(name);
    }
    return demo;
  }
})();

用法: 
非单例模式:var a = new Demo('Peter'); 
单例模式:

var b1 = Demo.getSingle('Peter');
var b2 = Demo.getSingle('Sufei');
b1 === b2;//true,都引用的是new Demo('Peter')

通过代理类来实现单例:

var ProxyDemo = (function(){
  var demo = null;
  return function(name){
    if(!demo){
      demo = new Demo(name);
    }
    return demo;
  }
})();

用法: 
非单例模式:var a = new Demo('Peter');
单例模式:var b = new ProxyDemo('Peter'); 

二. 惰性单例模式:只在需要的时候才创建该单例; 
以下是通用惰性单例的创建方法:

var getSingle = function(foo){
  var single = null;
  return function(){
    return single || (single = foo.apply(this,arguments));
  }
};

用法:

var createLoginLayer = function(){
  var frag = document.createDocumentFragment();
  var div = document.createElement('div');
  div.style.display = 'none';
  //以下给div添加其它登录元素
  ...
  document.body.appendChild(frag.appendChild(div));
  return div;
}
var createSingleLoginLayer = getSingle(createLoginLayer);
//当用户第一次点击按钮(id = 'lgBtn')时,来创建并显示登录窗口,之后重复点击按钮不会重复创建;
document.getElementById('lgBtn').onclick = function(){
  var lg = createSingleLoginLayer();
  lg.style.display = 'block';
}

附:缓存函数的计算结果,如计算一个数的数列 
以下是不缓存的写法,非常慢!

function foo(n){
  results = n < 2 ? n : foo(n - 1) + foo(n - 2);
  return results;
}
console.log(foo(40));//得计算好几秒

以下是缓存写法,基本瞬间出结果!

var cache = {};
function foo(n){
  if(!cache[n]){
    cache[n] = n < 2 ? n : foo(n - 1) + foo(n - 2);
  }
  return cache[n];
}
console.log(foo(100));

更好的写法:

var foo = (function(){
  var cache = {};
  return function(n){
    if(!cache[n]){
      cache[n] = n < 2 ? n : foo(n - 1) + foo(n - 2);
    }
    return cache[n];
  };
})();
console.log(foo(100));

参考文献:
 《JavaScript模式》
 《JavaScript设计模式与开发实践》

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript XML和string相互转化实现代码
Jul 04 Javascript
Javascript中arguments对象详解
Oct 22 Javascript
浅谈javascript对象模型和function对象
Dec 26 Javascript
浅谈JavaScript中的String对象常用方法
Feb 25 Javascript
使用Raygun来自动追踪AngularJS中的异常
Jun 23 Javascript
js 求时间差的实现代码
Apr 26 Javascript
基于Turn.js 实现翻书效果实例解析
Jun 20 Javascript
JavaScript中的对象继承关系
Aug 01 Javascript
JS日期对象简单操作(获取当前年份、星期、时间)
Oct 26 Javascript
Vue集成Iframe页面的方法示例
Dec 12 Javascript
微信小程序 swiper 组件遇到的问题及解决方法
May 26 Javascript
vue实现简单数据双向绑定
Apr 28 Vue.js
很酷的星级评分系统原生JS实现
Aug 25 #Javascript
jQuery 利用$.ajax 时获取原生XMLHttpRequest 对象的方法
Aug 25 #Javascript
轻松掌握JavaScript策略模式
Aug 25 #Javascript
Javascript 6里的4个新语法
Aug 25 #Javascript
Javascript实现代码折叠功能
Aug 25 #Javascript
深入浅出ES6之let和const命令
Aug 25 #Javascript
PhotoSwipe异步动态加载图片方法
Aug 25 #Javascript
You might like
php数组应用之比较两个时间的相减排序
2008/08/18 PHP
PHP使用数组依次替换字符串中匹配项
2016/01/08 PHP
php版阿里云OSS图片上传类详解
2016/12/01 PHP
extjs 学习笔记(三) 最基本的grid
2009/10/15 Javascript
JavaScript 动态添加表格行 使用模板、标记
2009/10/24 Javascript
javascript 多种搜索引擎集成的页面实现代码
2010/01/02 Javascript
JQuery自适应IFrame高度(支持嵌套 兼容IE,ff,safafi,chrome)
2011/03/28 Javascript
jQuery 翻牌或百叶窗效果(内容三秒自动切换)
2012/06/14 Javascript
jquery Tab效果和动态加载的简单实例
2013/12/11 Javascript
JavaScript闭包实例讲解
2014/04/22 Javascript
使用GruntJS构建Web程序之合并压缩篇
2014/06/06 Javascript
jquery中的常用事件bind、hover、toggle等示例介绍
2014/07/21 Javascript
JS控制弹出新页面窗口位置和大小的方法
2015/03/02 Javascript
js实现无限级树形导航列表效果代码
2015/09/23 Javascript
详解Bootstrap按钮
2016/01/04 Javascript
AngularJS ng-bind-html 指令详解及实例代码
2016/07/30 Javascript
详解angular element()方法使用
2017/04/08 Javascript
AngularJS自定义指令实现面包屑功能完整实例
2017/05/17 Javascript
php 修改密码实现代码
2017/05/24 Javascript
使用socket.io实现简单聊天室案例
2018/01/02 Javascript
JavaScript动态加载重复绑定问题
2018/04/01 Javascript
Mint UI组件库CheckList使用及踩坑总结
2018/12/20 Javascript
jQuery实现适用于移动端的跑马灯抽奖特效示例
2019/01/18 jQuery
JavaScript和TypeScript中的void的具体使用
2019/09/12 Javascript
Vue实现鼠标经过文字显示悬浮框效果的示例代码
2020/10/14 Javascript
python基础教程之字典操作详解
2014/03/25 Python
python操作mysql中文显示乱码的解决方法
2014/10/11 Python
python实现将文件夹下面的不是以py文件结尾的文件都过滤掉的方法
2018/10/21 Python
浅谈Python3多线程之间的执行顺序问题
2020/05/02 Python
如何更换python默认编辑器的背景色
2020/08/10 Python
利用 CSS3 实现的无缝轮播功能代码
2017/09/25 HTML / CSS
AmazeUI底部导航栏与分享按钮的示例代码
2020/08/18 HTML / CSS
莫斯科绝对前卫最秘密的商店:SVMoscow
2017/10/23 全球购物
目标责任书范文
2014/04/14 职场文书
禁毒宣传标语
2014/06/19 职场文书
2015年乡镇统计工作总结
2015/04/22 职场文书