轻松掌握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使Div居中并随网页大小改变而改变
Jun 24 Javascript
javaScript实现滚动新闻的方法
Jul 30 Javascript
node.js程序作为服务并在windows下开机自启动(用forever)
Mar 29 Javascript
详解使用angularjs的ng-options时如何设置默认值(初始值)
Jul 18 Javascript
Vue代码分割懒加载的实现方法
Nov 23 Javascript
使用vue2实现购物车和地址选配功能
Mar 29 Javascript
vue webpack实用技巧总结
Apr 24 Javascript
JavaScript设计模式之单例模式原理与用法实例分析
Jul 26 Javascript
layui禁用侧边导航栏点击事件的解决方法
Sep 25 Javascript
es6函数name属性功能与用法实例分析
Apr 18 Javascript
JavaScript oncopy事件用法实例解析
May 13 Javascript
vue+element-ui JYAdmin后台管理系统模板解析
Jul 28 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中理解print EOT分界符和echo EOT的用法区别小结
2010/02/21 PHP
PHP number_format() 函数定义和用法
2012/06/01 PHP
ThinkPHP学习笔记(一)ThinkPHP部署
2014/06/22 PHP
访问编码后的中文URL返回404错误的解决方法
2014/08/20 PHP
PHP入门教程之图像处理技巧分析
2016/09/11 PHP
PHP+Redis事务解决高并发下商品超卖问题(推荐)
2020/08/03 PHP
JQuery 初体验(建议学习jquery)
2009/04/25 Javascript
利用js实现选项卡的特别效果的实例
2013/03/03 Javascript
一个仿糯米弹框效果demo
2014/07/22 Javascript
在JavaScript中操作数组之map()方法的使用
2015/06/09 Javascript
安装使用Mongoose配合Node.js操作MongoDB的基础教程
2016/03/01 Javascript
Bootstrap CSS组件之导航条(navbar)
2016/12/17 Javascript
JS实现拖拽的方法分析
2016/12/20 Javascript
xmlplus组件设计系列之图标(ICON)(1)
2017/05/05 Javascript
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
Bootstrap模态对话框用法简单示例
2018/08/31 Javascript
Vue.js自定义指令学习使用详解
2019/10/19 Javascript
nodejs中使用archive压缩文件的实现代码
2019/11/26 NodeJs
快速解决element的autofocus失效问题
2020/09/08 Javascript
python2.7删除文件夹和删除文件代码实例
2013/12/18 Python
使用python的chardet库获得文件编码并修改编码
2014/01/22 Python
Python使用xlrd读取Excel格式文件的方法
2015/03/10 Python
放弃 Python 转向 Go语言有人给出了 9 大理由
2017/10/20 Python
python并发编程之线程实例解析
2017/12/27 Python
Django 实现购物车功能的示例代码
2018/10/08 Python
Python中的Socket 与 ScoketServer 通信及遇到问题解决方法
2019/04/01 Python
python爬虫 execjs安装配置及使用
2019/07/30 Python
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
HTML5 script元素async、defer异步加载使用介绍
2013/08/23 HTML / CSS
学生喝酒检讨书
2014/02/06 职场文书
普通党员对照检查材料
2014/08/28 职场文书
2014年小学校长工作总结
2014/12/08 职场文书
2015年会计工作总结范文
2015/05/26 职场文书
校运会加油稿大全
2015/07/22 职场文书
2016元旦主持人开场白
2015/12/03 职场文书
Python通过loop.run_in_executor执行同步代码 同步变为异步
2022/04/11 Python