轻松掌握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 相关文章推荐
Prototype ObjectRange对象学习
Jul 19 Javascript
jQuery中使用了document和window哪些属性和方法小结
Sep 13 Javascript
FireFox下XML对象转化成字符串的解决方法
Dec 09 Javascript
一个不错的字符串转码解码函数(自写)
Jul 31 Javascript
Javascript判断文件是否存在(客户端/服务器端)
Sep 16 Javascript
JS+CSS实现六级网站导航主菜单效果
Sep 28 Javascript
Highcharts 多个Y轴动态刷新数据的实现代码
May 28 Javascript
基于JS如何实现类似QQ好友头像hover时显示资料卡的效果(推荐)
Jun 09 Javascript
javascript类型系统——日期Date对象全面了解
Jul 13 Javascript
jQuery+css实现非常漂亮的水平导航菜单效果
Jul 27 Javascript
js字符串操作总结(必看篇)
Nov 22 Javascript
微信小程序实现给嵌套template模板传递数据的方式总结
Dec 18 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
咖啡冲泡指南 咖啡有哪些制作方式 单品咖啡 意式咖啡
2021/03/06 冲泡冲煮
Apache2 httpd.conf 中文版
2006/11/17 PHP
php中邮箱地址正则表达式实现与详解
2012/04/24 PHP
浅析关于PHP位运算的简单权限设计
2013/06/30 PHP
php中mail函数发送邮件失败的解决方法
2014/12/24 PHP
php动态函数调用方法
2015/05/21 PHP
PHP使用NuSOAP调用Web服务的方法
2015/07/18 PHP
页面只有一个text的时候,回车自动submit的解决方法
2010/08/12 Javascript
详谈javascript中的cookie
2015/06/03 Javascript
AngularJS包括详解及示例代码
2016/08/17 Javascript
Angular.JS学习之依赖注入$injector详析
2016/10/20 Javascript
从零开始搭建一个react项目开发
2018/02/09 Javascript
bootstrap中日历范围选择插件daterangepicker的使用详解
2018/04/17 Javascript
详解webpack4多入口、多页面项目构建案例
2018/05/25 Javascript
JavaScript 格式化数字、金额、千分位、保留几位小数、舍入舍去
2019/07/23 Javascript
js实现数字滚动特效
2019/12/16 Javascript
vue中实现回车键登录功能
2020/02/19 Javascript
JavaScript实现通讯录功能
2020/12/27 Javascript
[02:47]DOTA2英雄基础教程 野性怒吼兽王
2013/12/05 DOTA
[01:10]DOTA2次级职业联赛 - U5战队宣传片
2014/12/01 DOTA
Python两个整数相除得到浮点数值的方法
2015/03/18 Python
Python实现telnet服务器的方法
2015/07/10 Python
python3实现字符串的全排列的方法(无重复字符)
2018/07/07 Python
Python 实现取矩阵的部分列,保存为一个新的矩阵方法
2018/11/14 Python
Python实现二叉树的最小深度的两种方法
2019/09/30 Python
python脚本实现mp4中的音频提取并保存在原目录
2020/02/27 Python
Django 解决distinct无法去除重复数据的问题
2020/05/20 Python
浅谈Python中的继承
2020/06/19 Python
Django 权限管理(permissions)与用户组(group)详解
2020/11/30 Python
乌克兰排名第一的在线旅游超市:Farvater.Travel
2020/01/02 全球购物
幼儿园老师寄语
2014/04/03 职场文书
我的老师教学反思
2014/05/01 职场文书
四风问题班子对照检查材料
2014/09/27 职场文书
现役军人家属慰问信
2015/03/24 职场文书
二审答辩状格式
2015/05/22 职场文书
2016同学毕业寄语大全
2015/12/04 职场文书