轻松掌握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教程
Jun 09 Javascript
一步一步教你写一个jQuery的插件教程(Plugin)
Sep 03 Javascript
jQuery实现dialog设置focus焦点的方法
Jun 10 Javascript
Vue.js基础知识汇总
Apr 27 Javascript
JS在一定时间内跳转页面及各种刷新页面的实现方法
May 26 Javascript
AngularJS入门教程之XHR和依赖注入详解
Aug 18 Javascript
jQueryUI Datepicker组件设置日期高亮
Oct 13 Javascript
Vue + Webpack + Vue-loader学习教程之功能介绍篇
Mar 14 Javascript
extjs简介_动力节点Java学院整理
Jul 17 Javascript
vue中v-for循环给标签属性赋值的方法
Oct 18 Javascript
详解如何在Node.js的httpServer中接收前端发送的arraybuffer数据
Nov 11 Javascript
JS中的算法与数据结构之字典(Dictionary)实例详解
Aug 20 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代码(抓取网页中的邮箱地址)
2012/07/17 PHP
php获取文件内容最后一行示例
2014/01/09 PHP
PHP zip扩展Linux下安装过程分享
2014/05/05 PHP
php+MySQL判断update语句是否执行成功的方法
2014/08/28 PHP
php使用Jpgraph创建3D饼形图效果示例
2017/02/15 PHP
javascript xml为数据源的下拉框控件
2009/07/07 Javascript
jQuery 添加/移除CSS类实现代码
2010/02/11 Javascript
js本身的局限性 别让javascript做太多事
2010/03/23 Javascript
一个判断抢购时间是否到达的简单的js函数
2014/06/23 Javascript
判断window.onload是否多次使用的方法
2014/09/21 Javascript
js实现点击每个li节点,都弹出其文本值及修改
2016/12/15 Javascript
Vue.set()实现数据动态响应的方法
2018/02/07 Javascript
基于layui框架响应式布局的一些使用详解
2019/09/16 Javascript
[36:22]VP vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python3+PyQt5重新实现QT事件处理程序
2018/04/19 Python
python3下使用cv2.imwrite存储带有中文路径图片的方法
2018/05/10 Python
使用sklearn进行对数据标准化、归一化以及将数据还原的方法
2018/07/11 Python
python批量下载网站马拉松照片的完整步骤
2018/12/05 Python
获取django框架orm query执行的sql语句实现方法分析
2019/06/20 Python
Python qqbot 实现qq机器人的示例代码
2019/07/11 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
python使用paramiko实现ssh的功能详解
2020/03/06 Python
HTML5实现音频和视频嵌入的方法
2018/08/22 HTML / CSS
德国知名健康零食网上商店:Seeberger
2017/07/27 全球购物
皇家阿尔伯特英国官方商店:Royal Albert骨瓷
2019/03/25 全球购物
英国排名第一的餐具品牌:Denby Pottery
2019/11/01 全球购物
北京某公司的.net笔试题
2014/03/20 面试题
Python里面search()和match()的区别
2016/09/21 面试题
高一历史教学反思
2014/01/13 职场文书
幼教求职信
2014/03/12 职场文书
新闻传播专业求职信
2014/07/22 职场文书
群众路线剖析材料
2014/09/30 职场文书
上帝也疯狂观后感
2015/06/09 职场文书
Java框架入门之简单介绍SpringBoot框架
2021/06/18 Java/Android
Python 快速验证代理IP是否有效的方法实现
2021/07/15 Python
Tomcat starup.bat 脚本实现开机自启动
2022/04/20 Servers