Iwen's blog Iwen's blog
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • Linux
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
复盘
关于

Iwen

不摸鱼的哥哥
首页
  • 前端文章

    • JavaScript
    • Vue
  • 学习笔记

    • 《JavaScript教程》笔记
    • 《JavaScript高级程序设计》笔记
    • 《ES6 教程》笔记
    • 《Vue》笔记
    • 《TypeScript 从零实现 axios》
    • 小程序笔记
  • HTML
  • CSS
  • 技术文档
  • GitHub技巧
  • Nodejs
  • 博客搭建
  • Linux
  • 学习
  • 面试
  • 心情杂货
  • 友情链接
  • 网站
  • 资源
  • Vue资源
  • 分类
  • 标签
  • 归档
复盘
关于
  • Vue

  • Vue进阶

  • CSS

  • ES6

  • Base

  • Core

  • Array

  • Object

  • String

  • Async

  • Browser

  • Http

  • 性能优化

  • 正则

  • 经典总结

  • 设计模式

    • 单例模式
    • 策略模式
    • 观察者模式
    • 代理模式
    • 职责链模式
  • 数据结构

  • 算法

  • 手写

  • TypeScript

  • 复盘
  • 设计模式
Mr.w
2020-11-29

单例模式

# 单例模式

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

实现的方法为先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这就确保了一个类只有一个实例对象。

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

试想一下,当我们单击登录按钮的时候,页面中会出现一个登录浮窗,而这个登录浮窗是唯一的,无论单击多少次登录按钮,这个浮窗都只会被创建一次,那么这个登录浮窗就适合用单例模式来创建。

class Modal {
	constructor(name) {
		this.name = name;
		this.getName();
	}
    getName() {
        return this.name;
    }
}
Modal.create = (function() {
    let instance = null;
    return function(name) {
        if (!instance) {
           instance = new Modal(name);
        }
        return instance
    }
})()
let a = Modal.create('aaa');
let b = Modal.create('bbb');

// 因为单例模式是只实例化一次,所以下面的实例是相等的
console.log(a, b) 	// 两个都是aaa
console.log(a === b) 	// true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

上述代码是一种简单版单例模式,通过js的立即执行函数和闭包函数,将初始实例确定,之后便可通过判定instance是否存在,果存在则直接返回,反之则创建了再返回,即确保一个类只有一个实例对象。

“透明版”单例模式:

用户从这个类创建对象的时候,可以像使用其他普通类一样

let Modal = (function(){
    let instance;
    return function(name) {
        if (instance) {
           return instance;
        }
        this.name = name;
        return instance = this;
    }
})();

Modal.prototype.getName = function() {
    return this.name
}

let a = new Modal('问题框');
let b = new Modal('回答框');

console.log(a === b); // true
console.log(a.getName());  // '问题框'
console.log(b.getName());  // '问题框'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

用代理实现:

跟之前不同的是,我们把负责管理单例的逻辑移到了代理类ProxySing中,这样一来,Modal就变成了一个普通类。

let Modal = function(name) {
    this.name = name
    this.getName()  
}

Modal.prototype.getName = function() {
    return this.name
}

let ProxySing = (function(){
    let instance;
    return function(name) {
        if (!instance) {
            instance = new Modal(name)
        }
        return instance
    }
})()

let a = new ProxySing('问题框');
let b = new ProxySing('回答框');

console.log(a === b); // true
console.log(a.getName());  // '问题框'
console.log(b.getName());  // '问题框'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
总结
策略模式

← 总结 策略模式→

最近更新
01
flex布局页面自适应滚动条问题
12-28
02
前后端分离开发请求接口跨域如何携带cookie的问题
12-28
03
怎么实现div长宽比固定width-height4比3
12-28
更多文章>
Theme by Vdoing | Copyright © 2017-2022 Iwen | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式