轻松掌握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拖拽(第一课 未兼容)拖拽思路
Mar 29 Javascript
jquery 简单应用示例总结
Aug 09 Javascript
原始XMLHttpRequest方法详情回顾
Nov 28 Javascript
js substring从右边获取指定长度字符串(示例代码)
Dec 23 Javascript
jQuery多项选项卡的实现思路附样式及代码
Jun 03 Javascript
js识别不同浏览器基于userAgent做判断
Jul 29 Javascript
jQuery实现切换页面过渡动画效果
Oct 29 Javascript
JS实现无缝循环marquee滚动效果
May 22 Javascript
Angular X中使用ngrx的方法详解(附源码)
Jul 10 Javascript
Vue.js实现实例搜索应用功能详细代码
Aug 24 Javascript
微信小程序错误this.setData报错及解决过程
Sep 18 Javascript
通过实例解析js可枚举属性与不可枚举属性
Dec 02 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批量删除数据
2007/01/18 PHP
PHP设计模式 注册表模式
2012/02/05 PHP
PHP If Else(elsefi) 语句
2013/04/07 PHP
PHP使用MPDF类生成PDF的方法
2015/12/08 PHP
关于PHP文件的自动运行方法分析
2016/05/13 PHP
Yii2实现增删改查后留在当前页的方法详解
2017/01/13 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
从阶乘函数对比Javascript和C#的异同
2012/05/31 Javascript
自定义的一个简单时尚js下拉选择框
2013/11/20 Javascript
JavaScript获取鼠标移动时的坐标(兼容IE8、chome谷歌、Firefox)
2014/09/13 Javascript
js实现文字垂直滚动和鼠标悬停效果
2015/12/31 Javascript
基于JQuery打造无缝滚动新闻步骤详解
2016/03/31 Javascript
详解JavaScript中this关键字的用法
2016/05/26 Javascript
JS基础随笔(菜鸟必看篇)
2016/07/13 Javascript
BootStrap中的表单大全
2016/09/07 Javascript
基于vue的下拉刷新指令和滚动刷新指令
2016/12/23 Javascript
js实现随机抽选效果、随机抽选红色球效果
2017/01/13 Javascript
js实现简单的计算器功能
2017/01/16 Javascript
浅谈Node 调试工具入门教程
2018/03/20 Javascript
layui时间控件选择时间范围的实现方法
2019/09/28 Javascript
JavaScript制作3D旋转相册
2020/08/02 Javascript
Vue中keep-alive组件的深入理解
2020/08/23 Javascript
[03:04]DOTA2英雄基础教程 影魔
2013/12/11 DOTA
python 网络编程常用代码段
2016/08/28 Python
Python编程scoketServer实现多线程同步实例代码
2018/01/29 Python
详谈套接字中SO_REUSEPORT和SO_REUSEADDR的区别
2018/04/28 Python
python 使用poster模块进行http方式的文件传输到服务器的方法
2019/01/15 Python
Python XlsxWriter模块Chart类用法实例分析
2019/03/11 Python
对python3.4 字符串转16进制的实例详解
2019/06/12 Python
Python实现迪杰斯特拉算法并生成最短路径的示例代码
2020/12/01 Python
移动端HTML5 input常见问题(小结)
2020/09/28 HTML / CSS
Rhone官方网站:男士运动服装、健身服装和高级运动服
2019/05/01 全球购物
解决方案设计综合面试题
2015/08/31 面试题
个人合作协议书范本
2014/04/18 职场文书
2015年采购员工作总结
2015/04/27 职场文书
教你使用TensorFlow2识别验证码
2021/06/11 Python