单例模式

定义:保证一个对象(类)仅有一个实例,并提供一个访问它的全局访问点;

实现原理:利用闭包来保持对一个局部变量的引用,这个变量保存着首次创建的唯一的实例;

主要用于:全局缓存、登录浮窗等只需要唯一一个实例的时候;

一. 为一个非单例模式对象(如: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';
}

创建单例的其它方法:

方法1:

function Universe() {
// 判断是否存在实例
if (typeof Universe.instance === 'object') {
return Universe.instance;
}
// 其它内容
this.start_time = 0;
this.bang = "Big";
// 缓存
Universe.instance = this;
// 隐式返回this
}
// 测试
var uni = new Universe();
var uni2 = new Universe();
console.log(uni === uni2); // true

方法2:

function Universe() {
// 缓存的实例
var instance = this;
// 其它内容
this.start_time = 0;
this.bang = "Big";
// 重写构造函数
Universe = function () {
return instance;
};
}

附:缓存函数的计算结果,如计算一个数的数列

以下是不缓存的写法,非常慢!

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单例模式的更多相关文章

  1. javascript单例模式的理解

    javascript单例模式的理解 阅读目录 理解单例模式 使用代理实现单例模式 理解惰性单例 编写通用的惰性单例 单例模式使用场景 回到顶部 理解单例模式 单例模式的含义是: 保证一个类只有一个实例 ...

  2. 轻松学习 JavaScript——第 6 部分:JavaScript 箭头函数

    JavaScript箭头函数是ECMAScript 6中引入的编写函数表达式的一种简便方法.通常,在JavaScript中,可以通过两种方式创建函数: 函数语句. 函数表达式. 可以如下所示创建函数语 ...

  3. 浅析Javascript单例模式

    定义 保证一个类仅有一个实例,并提供一个访问它的全局访问点 .就想我们在开发中有些对象只需要一个,例如window对象. 1. 实现单例模式 var Singleton = function( nam ...

  4. [转] JavaScript 单例模式

    定义 确保一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式使用的场景 比如线程池.全局缓存等.我们所熟知的浏览器的window对象就是一个单例,在JavaScript开发中,对于这种只需要 ...

  5. 轻松学习JavaScript十八:DOM编程学习之DOM简单介绍

    一DOM概述 DOM(文档对象模型)是HTML和XML的应用程序接口(API).DOM将把整个页面规划成由节点层级构成的文档. DOM描绘了一个层次化的节点树,执行开发者加入,移除和改动页面的某一部分 ...

  6. Javascript单例模式概念与实例

    前言 和其他编程语言一样,Javascript同样拥有着很多种设计模式,比如单例模式.代理模式.观察者模式等,熟练运用Javascript的设计模式可以使我们的代码逻辑更加清晰,并且更加易于维护和重构 ...

  7. 轻松理解JavaScript闭包

    摘要 闭包机制是JavaScript的重点和难点,本文希望能帮助大家轻松的学习闭包 一.什么是闭包? 闭包就是可以访问另一个函数作用域中变量的函数. 下面列举出常见的闭包实现方式,以例子讲解闭包概念 ...

  8. 轻松理解JavaScript之AJAX

    摘要 AJAX技术是网页构建的必备技能之一,本文希望能帮助大家轻松的学习这项技术 一.什么是ajax? ajax(异步javascript xml) 能够刷新局部网页数据而不是重新加载整个网页. 二. ...

  9. 分针网—每日分享: 怎么轻松学习JavaScript

    js给初学者的印象总是那么的"杂而乱",相信很多初学者都在找轻松学习js的途径.   我试着总结自己学习多年js的经验,希望能给后来的学习者探索出一条"轻松学习js之路& ...

随机推荐

  1. EntityFramework之原始查询如何查询未映射的值,你又知道多少?

    前言 今天又倒腾了下EF,如题所示,遇到了一些问题,并最终通过尝试找到了解决方案,可能不是最终的解决方案,若你有更好的解决方案,望告知,同时通过阅读此文,定让你收获不少. 引入 当我们查询时一直是中规 ...

  2. iOS开发之新浪微博山寨版代码优化

    之前发表过一篇博客“IOS开发之新浪围脖”,在编写代码的时候太偏重功能的实现了,写完基本功能后看着代码有些别扭,特别是用到的四种cell的类,重复代码有点多,所以今天花点时间把代码重构一下.为了减少代 ...

  3. 2014年百度之星程序设计大赛 - 初赛(第二轮)Chess

    题目描述:小度和小良最近又迷上了下棋.棋盘一共有N行M列,我们可以把左上角的格子定为(1,1),右下角的格子定为(N,M).在他们的规则中,“王”在棋盘上的走法遵循十字路线.也就是说,如果“王”当前在 ...

  4. spring @import和@importResource

    @ImportResource in spring imports application xml in configuration file which is using @Configuratio ...

  5. Cesium应用篇:3控件(5)CesiumInspector

    CesiumInspector控件并不是带来太多功能上的,但对开发人员来说,对于了解Cesium的渲染效果以及性能调优,还是一个很有价值的控件,特别是一些渲染状态下的问题,采用该控件,应该还是会有很多 ...

  6. ASP.NET Core中的ActionFilter与DI

    一.简介 前几篇文章都是讲ASP.NET Core MVC中的依赖注入(DI)与扩展点的,也许大家都发现在ASP.NET CORE中所有的组件都是通过依赖注入来扩展的,而且面向一组功能就会有一组接口或 ...

  7. redux+flux(一:入门篇)

    React是facebook推出的js框架,React 本身只涉及UI层,如果搭建大型应用,必须搭配一个前端框架.也就是说,你至少要学两样东西,才能基本满足需要:React + 前端框架. Faceb ...

  8. WCF学习系列三--【WCF Interview Questions – Part 3 翻译系列】

    http://www.topwcftutorials.net/2012/10/wcf-faqs-part3.html WCF Interview Questions – Part 3 This WCF ...

  9. 用javascript编写的小游戏(getElementById , setInterval , clearInterval , window.onload , innerText 和页面跳转, 标签的使用)

    (1)图片轮转 <script type="text/javascript" > ; setInterval(function(){ var dom=document. ...

  10. Linux环境中Openfire安装指南

    Linux环境中Openfire安装指南 安装环境: 安装软件:Openfire 4_1_0 http://download.igniterealtime.org/openfire/openfire_ ...