JavaScript 的优雅编程技巧:Singleton Pattern

简介: JavaScript 的优雅编程技巧:Singleton Pattern

JavaScript 的优雅编程技巧:Singleton Pattern

定义

  • 单例模式:保证一个类仅有一个实例,并提供一个访问的全局访问点。

特点

  1. 1. 仅有一个实例对象
  2. 2. 全局都可访问该实例
  3. 3. 主动实例化
  4. 4. 延迟实例化

类似单例模式的使用实践

  1. 1. jQuery, lodash, moment ....
  2. 2. 电商中的购物车(因为一个用户只有一个购物车)
  3. 3. Vue 或 React 中全局状态管理(Vuex、Redux、Pinia)
  4. 4. 全局组件

关键步骤及实现

  • 关键步骤:实现一个标准的单例模式其实就是用一个变量来表示是否已经为当前类创建过实例化对象,若创建过,在下次获取或创建实例时直接返回之前创建的实例化对象即可
  • 如下代码:可称为:简单版 单例模式
var CreateStr = function (str) {
    this.str = str;
    this.instance = null;
};
CreateStr.prototype.getStr = function () {
    console.log(this.str);
};
CreateStr.getInstance = function (str) {
    if (!this.instance) {
        this.instance = new CreateStr(str);
    }
    return this.instance;
};
var a = CreateStr.getInstance('s1');
var b = CreateStr.getInstance('s2');
console.log('a ------>', a); // CreateStr { name: 's1', instance: null }
console.log('b ------>', b); // CreateStr { name: 's1', instance: null }
a.getStr(); //  s1
b.getStr(); //  s1
console.log(a === b); // true
  • 以上通过构造函数的方式来创建有一个问题,这个类不具有透明性(调用者并不知道这是一个单例类),因为这里使用的是 Person.getInstance 的方法来获取的实例化对象。
  • 改进后:可称为:透明版 单例模式
var CreateStr = (function () {
    var instance = null;
    return function (str) {
        if (instance) {
            return instance;
        }
        this.str = str;
        return (instance = this);
    };
})();
CreateStr.prototype.getStr = function () {
    console.log(this.str);
};
let a = new CreateStr('s1');
let b = new CreateStr('s2');
console.log('a ------>', a); // { str: 's1' }
console.log('b ------>', b); // { str: 's1' }
a.getStr(); //  s1
b.getStr(); //  s1
console.log(a === b); // true
  • 通过以上的改进方式,主要目的是使用 new 操作符来获取单列对象。
  • 但以上代码还有一个问题,就是当我们需要创建很多个字符串时,要让这个单例类变成一个可产生多个实例的类,所有我们要将管理单例的操作和对象创建的操作分离开来。
  • 再次改进后:可称为:代理版 单例模式
function CreateStr(str) {
    this.str = str;
    this.getStr();
}
CreateStr.prototype.getStr = function () {
    console.log(this.str);
};
var ProxyObj = (function () {
    var instance = null;
    return function (str) {
        if (!instance) {
            instance = new CreateStr(str);
        }
        return instance;
    };
})();
var a = new ProxyObj('s1');
var b = new ProxyObj('s2');
console.log('a ------>', a); // CreateStr { str: 's1' }
console.log('b ------>', b); // CreateStr { str: 's1' }
a.getStr(); //  s1
b.getStr(); //  s1
console.log('b ------>', a === b); // true

适用场景

  1. 1. 全局缓存管理器
  2. 2. 消息总线
  3. 3. 购物车
  4. 4. 全局状态管理
  5. 5. 全局事件管理器

优缺点

  • 优点:
  1. 1. 全局访问和单一实例:因为全局仅有一个实例对象,所以对单例的多个实例化都会得到的同一个实例,这就可以确保所有的对象都可访问一个实例。
  2. 2. 节省资源:因为全局仅有一个实例对象,所以可节约系统资源,避免频繁创建和销毁对象,造成系统性能的浪费
  • 缺点:
  1. 1. 违反单一职责原则:单例模式往往负责创建和管理实例,可能会导致职责过重
  2. 2. 紧密耦合:引入了全局访问,使代码过度依赖,难以维护和测试

Tip: 文章部分内容参考于曾探大佬的《JavaScript 设计模式与开发实践》。文章仅做个人学习总结和知识汇总

特殊字符描述

问题标注 Q:(question)答案标注 R:(result)注意事项标准:A:(attention matters)详情描述标注:D:(detail info)总结标注:S:(summary)分析标注:Ana:(analysis)提示标注:T:(tips)

相关文章
|
设计模式 存储 前端开发
使用 JS 快速理解 Container/Presentational Pattern
在现代Web前端开发中,构建可维护、可扩展的应用程序变得越来越重要。为了实现这一目标,开发者需要遵循一些设计模式和最佳实践。其中之一是Container/Presentational(容器/展示)模式,它是一种用于组织和管理前端代码的技术。 本文将深入探讨Container/Presentational模式的概念,介绍如何使用JavaScript实现它,并探讨它在开发中的应用场景、优点和缺点。我们还将介绍一些知名项目中使用到这种模式的实际案例。
256 0
|
设计模式 JavaScript 调度
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
132 0
JS案例:Observer Pattern(观察者模式)和Publisher-Subscriber Pattern(发布者/订阅者模式)
|
JavaScript 前端开发
深入理解 JavaScript 单例模式 (Singleton Pattern)
<button>Owen</button> <div id="modal"> <div class="main"> <div> 我是弹框 </div> </div> </div>
553 0
|
JavaScript 前端开发 Java
|
JavaScript
Js Pattern - Self Define Function
This pattern is useful when your function has some initial preparatory work to do andit needs to do it only once.
959 0
|
JavaScript 容器
Js Pattern - Namespace Pattern
bad code // BEFORE: 5 globals // Warning: antipattern // constructors function Parent() {} function Child() {} // a variable var some_var...
646 0
|
JavaScript 前端开发 设计模式
JavaScript设计模式学习(四)单件(Singleton Pattern)
  单件是JavaScript中最基本、最有用的设计模式,而你今后也会经常的使用这个模式。通过单件,我们可以把统一到一个逻辑单元中并且提供一个唯一的入口,这就保证你所有的引用都是用的这个全局资源。
909 0
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的客户关系管理系统附带文章源码部署视频讲解等
89 2
|
4月前
|
JavaScript Java 测试技术
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
基于springboot+vue.js+uniapp的小区物流配送系统附带文章源码部署视频讲解等
111 4