构造函数及es6类写单例模式

前言,什么叫做单例模式?简单点说,单例模式就是只能创建一个由构造函数及类的实体,多次调用得到的都是第一次new出来的对象。用处有,例如在需要全局管理的资源、频繁访问的配置信息、日志记录器、 数据库连接池 等情况下都可以使用单例模式来优化资源的使用和提高系统的性能。

一、传统的构造函数写单例模式

1、思路

要获取想只能获取一次实体对象,我们需要在new 构造函数的时候跳出本次new的过程,要跳出此次的new过程,我们需要一个函数变量去缓存上一次new的实体对象,用于判断构造函数已经new过。

2、普通的new构造函数

javascript 复制代码
// 生命instance变量缓存已new过的实体
let instance = null;
const createSingleton = function (name) {
    // 如果已经new过的跳出并返回缓存的实体,始终保持一个实体
    if (instance) return instance;
    this.name = name;
    instance = this; // 第一次new把实体返回
    return instance;
}
createInstance.prototype.getname = function () {
   console.log(this.name)
};
const a = new createSingleton ('aaa');
const b = new createSingleton ('bbb');
a.getname(); // aaa
b.getname(); // aaa

生命一个instance变量用于保存第一次new出来的实体对象,在构造函数原型上写一个getname的方法获取name的值。构造函数里判断构造函数是否已经实例化过,然后跳出并返回第一次的实体对象。这种写法有种缺陷,那就是会多出一个外部变量,可能会污染到全局的某个变量的,所以我使用闭包去解决这种问题。

3、结合闭包new构造函数

javascript 复制代码
// IIFE执行函数返回匿名函数当作构造函数,并利用闭包缓存实例化对象
const createInstance = (
    function () {
        let  instance =  null;
        return function (name) {
            // 非第一次实例化跳出并返回第一次实体化对象
            if (instance) return instance;
            this.name = name;
            instance = this;
            return instance;
        }
    }
)();

我们使用IIFE执行匿名函数,匿名函数里声明一个instance变量去缓存第一次实例化的对象,最后返回一个匿名函数当作构造函数。构造函数里利用instance去判断跳出此次实体化过程,在这个匿名函数里我们使用了闭包,所以我们在多次对这个构造函数实体化时,这个变量始终是第一次缓存下来的那个对象。

二、es6类写单例模式

1、思路

es6的类构造函数在类里面的constructor里,是个比较类似java类的一个类,所以我们可以在类里面写一个static的方法来获取这个类的实体(static是静态成员变量,可以让类不需要实例化就可以通过类去调用这个方法),并且做一些相应的判断去判断是否跳出并返回第一次的实体。

2、实现

javascript 复制代码
class Singleton {
    constructor(name) {
     this.name = name;
     this.instance = null;
    }
    // 构造一个广为人知的接口,供用户对该类进行实例化
    static getInstance(name) {
     if(!this.instance) {
      this.instance = new Singleton(name);
     }
     return this.instance;
    }
    getName () {
        console.log(this.name);
    }
}
Singleton.getInstance('aaaa').getName()
Singleton.getInstance('bbbb').getName()

在Singletom类的构造函数里同样写一个instance缓存第一次实体化类的对象,同时还有static方法getInstance获取实体化类的对象。getInstance方法用到this.instance去判断是否已经实体化过该类跳出返回实体类,否则实体化这个类。

相关推荐
驭渊的小故事3 小时前
MyBatis XML 开发实战:从配置到 CRUD 全解析
xml·java·mybatis
哦虎!8 小时前
【JavaEE】网络初识
java
for_ever_love__8 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
我是人✓9 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
欣栀♡9 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室9 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项9 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog9 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
秋饼10 小时前
Spring AI 2.0 结构化输出企业级实战:从 BeanOutputConverter 源码到生产级解析容错
java·ai·技术分享·后端开发
摇滚侠10 小时前
《计算机是如何工作的:人人都能懂的计算机软硬件工作原理》第 9 章 机器码与汇编语言 阅读笔记 9
java·开发语言·笔记