单例模式

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

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

JavaScript 中的单例模式

1. 使用命名空间

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

let people = {
name: "Jack",
age: 18,
play() {
console.log('i like game');
}
}

还可以动态地创建命名空间

// 定义对象
var MyApp = {};
// 对象的方法
MyApp.namespace = function( name ){
// 将参数分割成数组
var parts = name.split( '.' );
// 定义变量
var current = MyApp;
// 创建对象里面的属性
for ( var i in parts ){
if ( !current[ parts[ i ] ] ){
current[ parts[ i ] ] = {};
}
current = current[ parts[ i ] ];
}
};
MyApp.namespace( 'event' );
MyApp.namespace( 'dom.style' ); /******************* 上面没看懂没关系 ***********************/
// 上述代码等价于
var MyApp = {
event: {},
dom: {
style: {}
}
};

2. 使用闭包封装私有变量

var user = (function(){
var __name = 'sven',
__age = 29;
return {
getUserInfo: function(){
return __name + '-' + __age;
}
}
})();

我们用下划线来约定私有变量 __name__age ,它们被封装在闭包产生的作用域中,外部是访问不到这两个变量的,这就避免了对全局的命令污染。


实现一个标准的单例模式

var Singleton = function( name ){
this.name = name;
this.instance = null;
};
Singleton.prototype.getName = function(){
alert ( this.name );
};
Singleton.getInstance = function( name ){
if ( !this.instance ){
this.instance = new Singleton( name );
}
return this.instance;
};
var a = Singleton.getInstance( 'sven1' );
var b = Singleton.getInstance( 'sven2' );
alert ( a === b ); // true

我们通过 Singleton.getInstance 来获取 Singleton 类的唯一对象,这种方式相对简单,但有一个问题,就是增加了这个类的“不透明性”, Singleton 类的使用者必须知道这是一个单例类,跟以往通过 new XXX 的方式来获取对象不同,这里偏要使用 Singleton.getInstance 来获取对象。

透明的单例模式

var CreateDiv = (function(){
var instance;
var CreateDiv = function( html ){
if ( instance ){
return instance;
}
this.html = html;
this.init();
return instance = this;
};
CreateDiv.prototype.init = function(){
var div = document.createElement( 'div' );
div.innerHTML = this.html;
document.body.appendChild( div );
};
return CreateDiv;
})();
var a = new CreateDiv( 'sven1' );
var b = new CreateDiv( 'sven2' );
alert ( a === b ); // true

为了把 instance 封装起来,我们使用了自执行的匿名函数和闭包,并且让这个匿名函数返回

真正的 Singleton 构造方法,这增加了一些程序的复杂度

3. 用代理实现单例模式

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:
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' );
alert ( a === b );

通过引入代理类的方式,我们同样完成了一个单例模式的编写,跟之前不同的是,现在我们

把负责管理单例的逻辑移到了代理类 proxySingletonCreateDiv 中。这样一来,CreateDiv 就变成了一个普通的类,它跟 proxySingletonCreateDiv 组合起来可以达到单例模式的效果。

惰性单例

惰性单例指的是在需要的时候才创建对象实例。

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();

通过以上方法我们就可以做到只有在使用的时候才初始化,从而达到节约资源的目的

目前对于单例模式的理解就这么多,以后有了新的理解会继续更新的,溜了溜了(~ ̄▽ ̄)~

js 设计模式——单例模式的更多相关文章

  1. js设计模式-单例模式

      JavaScript中的单例模式是最常用的.最基本的设计模式,它提供了一种命名空间,减少全局变量泛滥的代码管理机制: 1.最常见的单例模式: [javascript] view plain cop ...

  2. JS设计模式——单例模式剖析

    转载于原文地址:https://blog.csdn.net/q1056843325/article/details/52933426 举一个通俗的例子,在页面中点击登录按钮,弹出了一个登录浮窗,这个登 ...

  3. [js]js设计模式-单例模式

    单例模式 不同模块之间需要同时开发, // 单例模式: 把描述同一个事物的属性和方法放在同一个内存空间下. // 优点: 分组,防止冲突 // p1 p2也叫做命名空间(模块开发) var p1 = ...

  4. [转]JS设计模式-单例模式(二)

    单例模式是指保证一个类仅有一个实例,并提供一个访问它的全局访问点. 单例模式是一种常用的模式,有一些对象往往只需要一个,比如线程池.全局缓存.浏览器中的window对象等.在javaScript开发中 ...

  5. ES6教程-字符串,函数的参数,了解函数的arguments对象,js面向对象,设计模式-单例模式,解构赋值

    前言 主要讲解了ES6对字符串的拓展,包括includes,startsWith和endsWith,另外增加了字符串模板. Start includes()是否包含 startsWith()以什么开头 ...

  6. JS设计模式(一)

    刚入职时,看过一段时间的设计模式,似懂非懂.不知不觉过去七个月了,对JS的理解更深刻了,数据结构与算法的基础也基本上算是过了一遍了,接下来要把设计模式搞定,然后不再深层次研究JS了,而是学习前端自动化 ...

  7. JavaScript设计模式-单例模式、模块模式(转载 学习中。。。。)

    (转载地址:http://technicolor.iteye.com/blog/1409656) 之前在<JavaScript小特性-面向对象>里面介绍过JavaScript面向对象的特性 ...

  8. js设计模式总结1

    js设计模式有很多种,知道不代表会用,更不代表理解,为了更好的理解每个设计模式,对每个设计模式进行总结,以后只要看到总结,就能知道该设计模式的作用,以及模式存在的优缺点,使用范围. 本文主要参考张容铭 ...

  9. JS实现单例模式的多种方案

    JS实现单例模式的多种方案 今天在复习设计模式中的-创建型模式,发现JS实现单例模式的方案有很多种,稍加总结了一下,列出了如下的6种方式与大家分享 大体上将内容分为了ES5(Function)与ES6 ...

随机推荐

  1. [视频教程] 如何在Linux深度系统deepin下安装docker

    笔记: 安装docker的命令 curl -sSL https://get.docker.com/ | sh service docker start 排查错误的命令 strace 视频地址在此:ht ...

  2. 1. Linux基本命令

    1. Linux 基本操作 1 基本命令 序号 命令 对应英文 作用 1 ls list 查看当前文件夹下的内容 2 pwd print work directory 查看当前所在文件夹 3 Cd [ ...

  3. ScratchJr是什么,有什么作用

    什么是ScratchJr? ScratchJr是一个入门级的编程语言,可以让5到7岁的小朋友去创建他们的互动故事和游戏.孩子们使用图形化的程序积木让角色移动.跳跃.舞蹈.唱歌.孩子们可以利用绘图编辑器 ...

  4. session.invalidate() 退出登录

    当浏览器第一次请求时,服务器创建一个session对象,同时生成一个sessionId,并在此次响应中将sessionId 以响应报文的方式传回客户端浏览器内存或以重写url方式送回客户端,来保持整个 ...

  5. vs code 中配置git go

    { "window.zoomLevel": 1, "editor.fontSize": 15, //"files.autoSave": &q ...

  6. FFT_应用和例题

    卷积 现有两个定义在 N 上的函数 \(f(n),g(n)\),定义 \(f\) 和 \(g\) 的卷积(convolution)为 \(f \otimes g\) \[ (f \otimes g)( ...

  7. 【2019.8.9 慈溪模拟赛 T2】摘Galo(b)(树上背包)

    树上背包 这应该是一道树上背包裸题吧. 众所周知,树上背包的朴素\(DP\)是\(O(nm^2)\)的. 但对于这种体积全为\(1\)的树上背包,我们可以通过记\(Size\)优化转移时的循环上界,做 ...

  8. redis.windows.conf 配置注释

    . daemonize no Redis默认不是以守护进程的方式运行,可以通过该配置项修改,使用yes启用守护进程 . pidfile /var/run/redis_6379.pid 当Redis以守 ...

  9. Springboot使用ehcache缓存

    本文部分步骤继承于springboot使用cache缓存,如果有不清楚的,请移驾springboot使用cache缓存 ehcache是一种广泛使用的开源Java分布式缓存.主要面向通用缓存,Java ...

  10. 【前端知识体系-JS相关】对移动端和Hybrid开发的理解?

    1.hybrid是什么,为何使用hybrid呢? 概念: hybrid就是前端和客户端的混合开发 需要前端开发人员和客户端开发人员配合完成 某些环节也可能会涉及到server端 大前端:网页.APP. ...