轻松掌握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 Replace()的高级使用方法介绍
Jun 29 Javascript
js校验表单后提交表单的三种方法总结
Feb 28 Javascript
jquery实现select下拉框美化特效代码分享
Aug 18 Javascript
JS时间特效最常用的三款
Aug 19 Javascript
JS排序方法(sort,bubble,select,insert)代码汇总
Jan 30 Javascript
JavaScript制作简单分页插件
Sep 11 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
Nov 03 Javascript
javascript常用的设计模式
Feb 09 Javascript
js获取一组日期中最近连续的天数
May 25 Javascript
浅谈webpack-dev-server的配置和使用
May 17 Javascript
JS实现长图上下滚动效果
Mar 19 Javascript
浅谈vue获得后台数据无法显示到table上面的坑
Aug 13 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
mysql_fetch_row,mysql_fetch_array,mysql_fetch_assoc的区别
2009/04/24 PHP
基于PHP服务端图片生成缩略图的方法详解
2013/06/20 PHP
php读取富文本的时p标签会出现红线是怎么回事
2014/05/13 PHP
JavaScript按位运算符的应用简析
2014/02/04 Javascript
jquery实现更改表格行顺序示例
2014/04/30 Javascript
js实现字符串转日期格式的方法
2015/05/20 Javascript
JS+JSP通过img标签调用实现静态页面访问次数统计的方法
2015/12/14 Javascript
Web前端新人笔记之jquery入门心得(新手必看)
2016/05/17 Javascript
js 获取图像缩放后的实际宽高,位置等信息
2017/03/07 Javascript
解决vue-router 二级导航默认选中某一选项的问题
2019/11/01 Javascript
Python中使用gzip模块压缩文件的简单教程
2015/04/08 Python
总结python实现父类调用两种方法的不同
2017/01/15 Python
关于Python如何避免循环导入问题详解
2017/09/14 Python
python机器学习之贝叶斯分类
2018/03/26 Python
Django框架创建mysql连接与使用示例
2019/07/29 Python
使用Python实现文字转语音并生成wav文件的例子
2019/08/08 Python
python中open函数的基本用法示例
2019/09/07 Python
Python批量安装卸载1000个apk的方法
2020/04/10 Python
Keras之fit_generator与train_on_batch用法
2020/06/17 Python
英国一家专门出售品牌鞋子的网站:Allsole
2016/08/07 全球购物
森海塞尔美国官网:Sennheiser耳机与耳麦
2017/07/19 全球购物
请写出char *p与"零值"比较的if语句
2014/09/24 面试题
资深生产主管自我评价
2013/09/22 职场文书
初中生自我评价
2014/02/01 职场文书
大学生优秀自荐信范文
2014/02/25 职场文书
经理任命书模板
2014/06/06 职场文书
2014最新版群众路线四风整改措施
2014/09/24 职场文书
工作失误检讨书范文
2015/01/26 职场文书
活动总结书怎么写
2015/05/11 职场文书
浅谈Python中的函数(def)及参数传递操作
2021/05/25 Python
MySQL 全文索引使用指南
2021/05/25 MySQL
MySQL 5.7常见数据类型
2021/07/15 MySQL
Python学习之时间包使用教程详解
2022/03/21 Python
Dubbo+zookeeper搭配分布式服务的过程详解
2022/04/03 Java/Android
vue如何实现关闭对话框后刷新列表
2022/04/08 Vue.js
JavaScript实现音乐播放器
2022/08/14 Javascript