轻松掌握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 String 的扩展方法集合
Jun 01 Javascript
禁用JavaScript控制台调试的方法
Mar 07 Javascript
Jquery通过JSON字符串创建JSON对象
Aug 24 Javascript
jQuery中is()方法用法实例
Jan 06 Javascript
javascript实现日期按月份加减
May 15 Javascript
举例简介AngularJS的内部语言环境
Jun 17 Javascript
JS时间特效最常用的三款
Aug 19 Javascript
浅谈jquery的map()和each()方法
Jun 12 Javascript
jQuery插件autocomplete使用详解
Feb 04 Javascript
yii form 表单提交之前JS在提交按钮的验证方法
Mar 15 Javascript
vue实现点击展开点击收起效果
Apr 27 Javascript
Vue父子组件传值的一些坑
Sep 16 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 抽象类的简单应用
2011/09/06 PHP
php读取txt文件组成SQL并插入数据库的代码(原创自Zjmainstay)
2012/07/31 PHP
50个PHP程序性能优化的方法
2014/06/02 PHP
理清PHP在Linxu下执行时的文件权限方法
2017/06/07 PHP
ThinkPHP框架整合微信支付之JSAPI模式图文详解
2019/04/09 PHP
iframe 自适应高度[在IE6 IE7 FF下测试通过]
2009/04/13 Javascript
百度留言本js 大家可以参考下
2009/10/13 Javascript
javascript中创建对象的三种常用方法
2010/12/30 Javascript
datagrid框架的删除添加与修改
2013/04/08 Javascript
用Js实现的动态增加表格示例自己写的
2013/10/21 Javascript
Google官方支持的NodeJS访问API,提供后台登录授权
2014/07/29 NodeJs
js点击按钮实现水波纹效果代码(CSS3和Canves)
2016/09/15 Javascript
JavaScript 闭包详细介绍
2016/09/28 Javascript
微信小程序 for 循环详解
2016/10/09 Javascript
深入理解JavaScript的async/await
2018/08/05 Javascript
对vuejs的v-for遍历、v-bind动态改变值、v-if进行判断的实例讲解
2018/08/27 Javascript
JavaScript常用事件介绍
2019/01/21 Javascript
微信小程序中button去除默认的边框实例代码
2019/08/01 Javascript
Nodejs 微信小程序消息推送的实现
2021/01/20 NodeJs
详解Python中的__init__和__new__
2014/03/12 Python
Python、Javascript中的闭包比较
2015/02/04 Python
Python3 处理JSON的实例详解
2017/10/29 Python
Python下使用Scrapy爬取网页内容的实例
2018/05/21 Python
python科学计算之narray对象用法
2019/11/25 Python
Python3标准库之threading进程中管理并发操作方法
2020/03/30 Python
解决pycharm安装第三方库失败的问题
2020/05/09 Python
Argos官网:英国家喻户晓的百货零售连锁商
2017/04/03 全球购物
如何强制垃圾回收
2015/10/06 面试题
大学生职业规划前言模板
2013/12/27 职场文书
社会治安综合治理管理责任书
2014/04/16 职场文书
高考标语大全
2014/06/05 职场文书
父亲节活动策划方案
2014/08/24 职场文书
2014年电话销售工作总结
2014/12/01 职场文书
2014年后勤管理工作总结
2014/12/01 职场文书
学术会议邀请函
2015/01/30 职场文书
Python OpenCV超详细讲解调整大小与图像操作的实现
2022/04/02 Python