引言

本文摘自《JavaScript设计模式与开发实践》

在传统开发工程师眼里,单例就是保证一个类只有一个实例,实现的方法一般是先判断实例存在与否,如果存在直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。

在JavaScript里,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。

单例模式是一种常用的模式,有一些对象我们往往只需要一个,比如线程池、全局缓存、浏览器中的window对象等。

模式定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

模式实现

接近传统面向对象语言的实现

下面的实现是接近传统面向对象语言中的实现,单例对象从“类”中创建而来。在以类为中心的语言中,这是很自然的做法。比如在Java中,如果需要某个对象,就必须先定义一个类,对象总是从类中创建而来的。

// 创建div类:CreateDiv
var CreateDiv = function(html) {this.html = html;this.init();
};CreateDiv.prototype.init = function() {var div = document.createElement('div');div.innerHTML = this.html;document.body.appendChild(div);
};// 代理类:proxySingletonCreateDiv,这里引进代理类,是为了将创建div与单例的实现分离开来,方便扩展
var ProxySingletonCreateDiv = (function() {var instance;return function(html) {if (!instance) {instance = new CreateDiv(html);}return instance;}
})();var a = new ProxySingletonCreateDiv('sven1');
var b = new ProxySingletonCreateDiv('sven2');console.log(a === b); // ture

运用JavaScript特性的实现

JavaScript其实是一门无类(class-free)语言,也正因为如此,生搬单例模式的概念并无意义。在JavaScript中创建对象的方法非常简单,既然我们只需要一个“唯一”的对象,为什么要为它先创建一个“类”呢?这无异于穿棉衣洗澡,传统的单例模式实现在JavaScript中并不适用。

单例模式的核心是确保只有一个实例,并提供全局访问。因此在JavaScript里把全局变量当成单例来使用,单例作为一个命名空间提供者,从全局命名空间里提供一个唯一的访问点来访问该对象。

在JavaScript里,实现单例的方式有很多种,其中最简单的一个方式是使用对象字面量的方法,其字面量里可以包含大量的属性和方法:

var mySingleton = {property1: "something",property2: "something else",method1: function() {console.log('hello world');}
};

如果以后要扩展该对象,你可以添加自己的私有成员和方法,然后使用闭包在其内部封装这些变量和函数声明。只暴露你想暴露的public成员和方法,样例代码如下:

var mySingleton = function() {/// 这里声明私有变量和方法var privateVariable = 'something private';function showPrivate() {console.log(privateVariable);}// 公有变量和方法(可以访问私有变量和方法)return {publicMethod: function() {showPrivate();},publicVar: 'the public can see this!'};
};var single = mySingleton();
single.publicMethod();  // 输出 'something private'
console.log(single.publicVar); // 输出 'the public can see this!'

当然,为了节约资源的目的,我们可以只在使用的时候才初始化该单例,实现的方式就是在另一个方法中进行初始化:

var Singleton = (function() {var instantiated;function init() {// 这里定义单例代码return {publicMethod: function() {console.log('hello world');},publicProperty: 'test'};}return {getInstance: function() {if (!instantiated) {instantiated = init();}return instantiated;}};
})();// 调用公有的方法来获取实例
Singleton.getInstance().publicMethod();

其它实现

方法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;};
}// 测试
var uni = new Universe();
var uni2 = new Universe();
uni.bang = "123";
console.log(uni === uni2); // true
console.log(uni2.bang); // 123

方法3

function Universe() {// 缓存实例var instance;// 重新构造函数Universe = function Universe() {return instance;};// 后期处理原型属性Universe.prototype = this;// 实例instance = new Universe();// 重设构造函数指针instance.constructor = Universe;// 其它功能instance.start_time = 0;instance.bang = "Big";return instance;
}// 测试
var uni = new Universe();
var uni2 = new Universe();
console.log(uni === uni2); // true// 添加原型属性
Universe.prototype.nothing = true;var uni = new Universe();Universe.prototype.everything = true;var uni2 = new Universe();console.log(uni.nothing); // true
console.log(uni2.nothing); // true
console.log(uni.everything); // true
console.log(uni2.everything); // true
console.log(uni.constructor === Universe); // true

方式4

var Universe;(function () {var instance;Universe = function Universe() {if (instance) {return instance;}instance = this;// 其它内容this.start_time = 0;this.bang = "Big";};
}());//测试代码
var a = new Universe();
var b = new Universe();
alert(a === b); // true
a.bang = "123";
alert(b.bang); // 123

JavaScript设计模式与开发实践 - 单例模式相关推荐

  1. JavaScript设计模式与开发实践系列之单例模式

    本系列为<JavaScript设计模式与开发实践>(作者:曾探)学习总结,如想深入了解,请支持作者原版 单例模式 实现单例模式 单例模式的定义是:保证一个类仅有一个实例,并提供一个访问它的 ...

  2. 《JavaScript设计模式与开发实践》阅读摘要

    <JavaScript设计模式与开发实践>作者:曾探 系统的介绍了各种模式,以及js中的实现.应用,以及超大量高质量代码,绝对值得一读 面向对象的js 静态类型:编译时便已确定变量的类型 ...

  3. 专访《Javascript设计模式与开发实践》作者曾探:爱编程 爱生活

     专访<Javascript设计模式与开发实践>作者曾探:爱编程 爱生活 发表于12小时前| 2742次阅读| 来源CSDN| 8 条评论| 作者夏梦竹 专访曾探图书作者Javascr ...

  4. javascript设计模式(javascript设计模式与开发实践读书笔记)

    javascript设计模式(javascript设计模式与开发实践读书笔记) 单例模式 策略模式 代理模式 迭代器模式 发布-订阅模式 命令模式 组合模式 模板方法模式 享元模式 职责链模式 中介者 ...

  5. JavaScript设计模式与开发实践(网课学习)

    Js设计模式与开发实践 面向对象 5大设计原则 23种设计模式(实际只有21种) 设计模式主要分为下面三大类 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模 ...

  6. 《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

    在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方面,继承这种功能复 ...

  7. JavaScript设计模式与开发实践——JavaScript的多态

    "多态"一词源于希腊文polymorphism,拆开来看是poly(复数)+ morph(形态)+ ism,从字面上我们可以理解为复数形态. 多态的实际含义是:同一操作作用于不同的 ...

  8. JS代理模式《JavaScript设计模式与开发实践》阅读笔记

    代理模式 代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问. 保护代理和虚拟代理 保护代理:当有许多需求要向某对象发出一些请求时,可以设置保护代理,通过一些条件判断对请求进行过滤. 虚拟 ...

  9. 《JavaScript设计模式与开发实践》模式篇(5)—— 观察者模式

    发布-订阅模式又叫观察者模式,它定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都将得到通知.在 JavaScript 开发中,我们一般用事件模型 来替代传统的发布- ...

最新文章

  1. Swift语法3.03(类型Types)
  2. 去大公司和小公司实习对比
  3. lstm网络一般训练多少轮_做网络推广一般多少钱:做网络推广 你一定会用到这个产品...
  4. java 将 ResultSet 转化为 json格式
  5. pytorch nonzero_[深度学习框架]PyTorch常用代码段
  6. Java对Json文件中数据排序_[Java教程]js之封装sort实现json格式数据的排序
  7. SPRAY 光谱光线追迹仿真软件
  8. csapp--键盘驱动程序的分析与修改
  9. 图形化开发(五)011-Three.js之Geometry几何体——立方体、圆形、圆锥
  10. 索尼koov机器人比赛_搭上“想象”去成长 索尼KOOV可编程教育机器人评测
  11. 关于vcard通讯录格式解析-微信二维码解析
  12. Android中 手机震动功能的实现
  13. 怎样恢复内存卡的视频文件?(图文操作解析)
  14. vue项目接入eslint、prettier、husky+lint-staged
  15. android锁屏原理(一)
  16. 2021会是怎样的一年
  17. C++:从入门到放弃[2]变量和读入
  18. 2018 年度读书总结
  19. 29. 大数据---hive的常用函数(一(最全的函数操作))
  20. 容联云2021年Q1财报出炉:净金额留存率超110%

热门文章

  1. cesium 加载网格
  2. html 显示接口数据格式化,科技常识:html格式化输出JSON示例(测试接口)
  3. python is beautiful_python自动化报告BeautifulReport用法
  4. 临时限速服务器系统ppt,临时限速系统讲解.pptx
  5. 我的世界服务器换披风的网站,我的世界评测_我的世界正版披风怎么换|或_游戏手机游戏-中关村在线...
  6. 获取Linux的方法,CDN Linux系统中获取LDNS的方法
  7. spring boot 教程(三)配置详解
  8. 男孩子初中毕业学计算机技术,男孩子初中毕业学什么技术好就业
  9. python会议室系统预定_会议室预定系统
  10. elementui如何在input 框中搜索_【挑战自学Python编程】第八天:while循环以及input()函数...