轻松掌握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 相关文章推荐
获取DOM对象的几种扩展及简写
Oct 09 Javascript
IE 条件注释详解总结(附实例代码)
Aug 29 Javascript
jquery validation插件表单验证的一个例子
Mar 03 Javascript
jQuery判断复选框是否勾选的原理及示例
May 21 Javascript
返回顶部按钮响应滚动且动态显示与隐藏
Oct 14 Javascript
JS限定手机版中图片大小随分辨率自动调整的方法
Dec 05 Javascript
简单实现Bootstrap标签页
Aug 09 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
Apr 21 jQuery
node 利用进程通信实现Cluster共享内存
Oct 27 Javascript
Vue2.0 slot分发内容与props验证的方法
Dec 12 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
Aug 02 jQuery
vue中的使用token的方法示例
Mar 10 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/12/10 PHP
让codeigniter与swfupload整合的最佳解决方案
2014/06/12 PHP
php+ajax实现图片文件上传功能实例
2014/06/17 PHP
php身份证号码检查类实例
2015/06/18 PHP
yii2.0整合阿里云oss上传单个文件的示例
2017/09/19 PHP
基于jquery的inputlimiter 实现字数限制功能
2010/05/30 Javascript
JavaScript 小型打飞机游戏实现原理说明
2010/10/28 Javascript
使用JavaScript开发IE浏览器本地插件实例
2015/02/18 Javascript
原生js实现jquery函数animate()动画效果的简单实例
2016/08/21 Javascript
微信小程序 向左滑动删除功能的实现
2017/03/10 Javascript
老生常谈angularjs中的$state.go
2017/04/24 Javascript
jQuery实现用户信息表格的添加和删除功能
2017/09/12 jQuery
vue绑定的点击事件阻止冒泡的实例
2018/02/08 Javascript
原生js实现Flappy Bird小游戏
2018/12/24 Javascript
react结合bootstrap实现评论功能
2020/05/30 Javascript
Node.JS如何实现JWT原理
2020/09/18 Javascript
vue组件是如何解析及渲染的?
2021/01/13 Vue.js
编写Python脚本抓取网络小说来制作自己的阅读器
2015/08/20 Python
一张图带我们入门Python基础教程
2017/02/05 Python
python中类变量与成员变量的使用注意点总结
2017/04/29 Python
Python实现单词翻译功能
2017/06/06 Python
Python制作豆瓣图片的爬虫
2017/12/28 Python
获取python文件扩展名和文件名方法
2018/02/02 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
Python xlrd excel文件操作代码实例
2020/03/10 Python
Python 实现将某一列设置为str类型
2020/07/14 Python
Python程序慢的重要原因
2020/09/04 Python
HTML5实现锚点时请使用id取代name
2013/09/06 HTML / CSS
美国高街时尚品牌:OASAP
2016/07/24 全球购物
HomeAway澳大利亚:预订你的度假屋,公寓、度假村、别墅等
2019/02/20 全球购物
英国的一家创新礼品和小工具零售商:Menkind
2019/08/24 全球购物
伊莱克斯阿根廷网上商店:Tienda Electrolux
2021/03/08 全球购物
Python里面如何拷贝一个对象
2014/02/17 面试题
高中生操行评语大全
2014/04/25 职场文书
2019年大学毕业生个人自我鉴定范文大全
2019/03/21 职场文书
HTML静态页面获取url参数和UserAgent的实现
2022/08/05 HTML / CSS