轻松掌握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 相关文章推荐
原生js实现复制对象、扩展对象 类似jquery中的extend()方法
Aug 30 Javascript
drag-and-drop实现图片浏览器预览
Aug 06 Javascript
jQuery简单验证上传文件大小及类型的方法
Jun 02 Javascript
JS简单获取及显示当前时间的方法
Aug 03 Javascript
Bootstarp基本模版学习教程
Feb 01 Javascript
详谈js中window.location.search的用法和作用
Feb 13 Javascript
JS实现的走迷宫小游戏完整实例
Jul 19 Javascript
基于BootStrap multiselect.js实现的下拉框联动效果
Jul 28 Javascript
jQuery结合jQuery.cookie.js插件实现换肤功能示例
Oct 14 jQuery
JavaScript EventEmitter 背后的秘密 完整版
Mar 29 Javascript
如何实现一个webpack模块解析器
Oct 24 Javascript
解决vue字符串换行问题(绝对管用)
Aug 06 Javascript
很酷的星级评分系统原生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获取文件名后缀
2013/06/09 PHP
PHP 输出缓冲控制(Output Control)详解
2016/08/25 PHP
PHP实现递归目录的5种方法
2016/10/27 PHP
多个iframe自动调整大小的问题
2006/09/18 Javascript
jQuery 技巧大全(新手入门篇)
2009/05/12 Javascript
javascript setTimeout()传递函数参数(包括传递对象参数)
2010/04/07 Javascript
关于jQuery object and DOM element
2013/04/15 Javascript
javascript实现控制浏览器全屏
2015/03/30 Javascript
浅谈jQuery中setInterval()方法
2015/07/07 Javascript
浅谈JavaScript中的对象及Promise对象的实现
2015/11/15 Javascript
使用jQuery监听DOM元素大小变化
2016/02/24 Javascript
编写高质量JavaScript代码的基本要点
2016/03/02 Javascript
基于js里调用函数时,函数名带括号和不带括号的区别
2016/07/28 Javascript
浅谈js函数中的实例对象、类对象、局部变量(局部函数)
2016/11/20 Javascript
js实现网页同时进行多个倒计时功能
2019/02/25 Javascript
解决layui轮播图有数据不显示的情况
2019/09/16 Javascript
ES6实现图片切换特效代码
2020/01/14 Javascript
Vue.extend 登录注册模态框的实现
2020/12/29 Vue.js
python实现从网络下载文件并获得文件大小及类型的方法
2015/04/28 Python
人生苦短我用python python如何快速入门?
2018/03/12 Python
不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)
2019/04/16 Python
Django实现CAS+OAuth2的方法示例
2019/10/30 Python
使用pyhon绘图比较两个手机屏幕大小(实例代码)
2020/01/03 Python
使用python的turtle函数绘制一个滑稽表情
2020/02/28 Python
浅谈Python中re.match()和re.search()的使用及区别
2020/04/14 Python
7款设计巧妙的css3飘带状3D立体效果的导航菜单和表单窗口
2013/02/04 HTML / CSS
HTML5 input元素类型:email及url介绍
2013/08/13 HTML / CSS
HTML5新增元素如何兼容旧浏览器有哪些方法
2014/05/09 HTML / CSS
会计专业毕业生求职信分享
2014/01/03 职场文书
校庆口号
2014/06/20 职场文书
坎儿井导游词
2015/02/09 职场文书
2015年绩效考核工作总结
2015/05/23 职场文书
预备党员群众意见
2015/06/01 职场文书
PHP基本语法
2021/03/31 PHP
python异步的ASGI与Fast Api实现
2021/07/16 Python
MySQL学习之基础命令实操总结
2022/03/19 MySQL