JavaScript设计模式(一):单例模式

栏目: 后端 · 发布时间: 6年前

内容简介:停更许久,近期计划更新:设计模式系列。单例模式:限制类实例化次数只能一次,一个类只有一个实例,并提供全局访问点。(归属创建型设计模式)

停更许久,近期计划更新:设计模式系列。

JavaScript设计模式(一):单例模式

单例模式:限制类实例化次数只能一次,一个类只有一个实例,并提供全局访问点。(归属创建型设计模式)

模式特点

  1. 类只有一个实例
  2. 全局可访问该实例
  3. 自行实例化(主动实例化)
  4. 可推迟初始化,即延迟执行(与静态类/对象的区别)

实现方式

实现方式:使用一个变量存储类实例对象(值初始为 null/undefined )。进行类实例化时,判断类实例对象是否存在,存在则返回该实例,不存在则创建类实例后返回。多次调用类生成实例方法,返回的同一个实例对象。

代码实现

class Singleton {
  constructor(name) {
    this.name = name;
  }
  getName() {
    return this.name;
  }
}
Singleton.getInstance = (function () {
  let instance;
  return function (name) {
    if (!instance) {
      instance = new Singleton(name);
    }
    return instance;
  }
})();

var Winner = Singleton.getInstance('Winner');
var Looser = Singleton.getInstance('Looser');

console.log(Winner === Looser); // true
console.log(Winner.getName());  // 'Wiinner'
console.log(Looser.getName());  // 'Looser'

代码中定义了一个 Singleton 类,并定义 Singleton.getInstance() 方法来生成实例对象。而不是通过 new 操作符来创建类实例。

Singleton.getInstance() 中,通过闭包引用存储类实例的对象,判断类是否实例化过。(这里闭包的使用能够使 getInstance() 多次调用都能获取到之前类实例的存储值)。因此无论执行多少次 Singleton.getInstance() 方法,都只会返回同一个Singleton类实例对象。

使用场景

“单例模式的特点,意图解决:维护一个全局实例对象。”

  1. 引用第三方库
  2. 弹窗登录框
  3. 购物车
  4. 全局态管理 store (Vuex / Redux)

项目中引入第三方库时,重复加载库文件,全局只会实例化一个库对象,如 jQuerylodashmoment ..., 其实它们的实现方式也是单例模式应用的一种:

// 引入代码库 libs(库别名)
if (window.libs != null) {
  return window.libs;    // 直接返回
} else {
  window.libs = '...';   // 初始化
}

单例 设计模式 实现全局弹窗登录框:

class LoginModal {
    constructor() {
        const div = document.createElement('div');
        div.innerHTML = '登录框HTML内容';
        div.style.display = 'none';
        this.el = div;
        this.visible = false;
        document.body.append(div);
        return div;
    }
    show() {
        this.el.style.display = 'block';
    }
    hide() {
        this.el.style.display = 'none';
    }
    toggle() {
        this.visible = !this.visible;
        this.visible ? this.show() : this.hide();
    }
}

LoginModal.getInstance = (function() {
    let instance;
    return function() {
        if (!instance) {
            instance = new LoginModal();
        }
        return instance;
    }
})();

// 按钮切换显示登录框
document.getElementById('btn-login').addEventListener('click', function(){
    LoginModal.getInstance().toggle();
})

优缺点

  • 优点:适用单一对象,只生成一个对象实例,减少内存开销,避免频繁创建和销毁实例。
  • 缺点:不适用动态扩展对象,如通过对象继承扩展新对象。

TIPS: 多线程编程语言中,单例模式会涉及同步锁的问题。而JavaScript是单线程的编程语言,可忽略该问题。

参考文章

本文首发Github,期待Star!

https://github.com/ZengLingYong/blog

作者:以乐之名


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

A Philosophy of Software Design

A Philosophy of Software Design

John Ousterhout / Yaknyam Press / 2018-4-6 / GBP 14.21

This book addresses the topic of software design: how to decompose complex software systems into modules (such as classes and methods) that can be implemented relatively independently. The book first ......一起来看看 《A Philosophy of Software Design》 这本书的介绍吧!

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具