JS:单例模式 —— 百度考题 (二)

前言

今天我们来聊聊单例模式,在我们以往的文章中,我们讲过了代理模式,代理模式和单例模式都是设计模式的一种,感兴趣的小伙伴们可以先看看我的上篇文章,链接在此: 代理模式

设计模式是在软件设计中经常出现的一些问题的通用、可重用的解决方案。它们是经验丰富的开发人员为了解决特定类型的问题而提出的经过验证的设计思路。设计模式并不是一种可以直接的转化为代码的具体算法,而是描述问题和解决方案之间关系的抽象模型。

设计模式的主要目标是提供一种通用的、可重复使用的解决方案,帮助开发人员解决软件设计中常见的问题,提高代码的可维护性、可执行性和可扩展性。使用设计模式有助益于降低系统耦合度,使得代码更容易理解和维护。

我们先来看看上一篇文章中留下来的问题,同样它也是百度的一道考题,要求不管new 多少次, 它都只给你返回第一次创建的那唯一的一个实例,意思就是让s1 和 s2 相等。

js 复制代码
class SingleDog{
    show() {
        console.log("我是一个单例对象");
    }
}

const s1 = new SingleDog()
const s2 = new SingleDog()

console.log(s1 === s2);

最后判断s1 === s2时会输出什么呢?

在这份代码中,s1并且s2是通过相同的类SingleDog实例化得到的,但它们实际上是两个不同的对象。因此,s1 === s2比较的结果是false

最终通过new SingleDog()创建一个新的实例时,都会产生一个新的对象。即使这两个对象的结构和方法相同,它们在内存中是不同的实体,因此对它们进行严格一致性(===)的比较时会返回false

通过这个例子我们可以看出,类创造实例对象时跟构造函数创造实例对象一样,都会产生一个新的对象。

我们知道是因为new关键字才产生了一个新的实例对象,s1、s2里面存的是地址,是不相同的,那我们怎么样才能让s1 === s2呢?

单例模式

单例模式是一种设计模式,其目的是保证一个类只有一个实例

我们可以先来想想思路,我们怎么样才可以让 s1 和 s2 拥有相同地址呢?

  • new先生成一个地址

  • 判断地址是否存在

  • 若存在,不用new,将地址赋值给对象

我们来看看代码怎么写:

js 复制代码
class SingleDog{
    // 公共方法, 属于对象
    show(){
        console.log('我是一个单例对象');
    }
  
    // static intance
    static getInstance() {
        if (!SingleDog.instance) {
            SingleDog.instance = new SingleDog()
        }
        return SingleDog.instance
    }
}
// 类的方法
const s1 = SingleDog.getInstance()
const s2 = SingleDog.getInstance()
console.log(s1 === s2);
  • instanceSingleDog类的静态属性,存储了类的唯一实例。
  • getInstance是一个静态方法,用于获取SingleDog类的实例。在该方法内部,检查instance是否已经存在,如果不存在,则创建一个新的实例并将其赋给instance,然后返回该实例。
  • 在代码的最后,通过调用SingleDog.getInstance()获取SingleDog类的实例。由于使用了单例模式的实现,s1s2实际引用相同的实例,因此s1 === s2true

这样的设计模式保证在整个应用程序中,只有一个SingleDog实例存在,防止了多次创建相同对象的情况。

静态方法

静态方法是附加在类本身上的方法,而不是类的实例上的方法。在JavaScript中,你可以使用关键字static来定义静态方法。静态方法可以通过类名直接调用,而不需要创建类的实例,比如:const s1 = SingleDog.getInstance(),const s2 = SingleDog.getInstance()

我们来看看输出结果,使用这种方法能不能实现让s1 和 s2 拥有相同的地址

我们还有另一种方法可以实现单例模式,那就是闭包,我们之前的文章也有讲过:

js 复制代码
class SingleDog {
    // 静态属性,用于存储单例实例
    static instance = null;

    // 静态方法,用于获取单例实例
    static getInstance() {
        if (!SingleDog.instance) {
            SingleDog.instance = new SingleDog();
        }
        return SingleDog.instance;
    }

    // 实例方法
    show() {
        console.log("我是一个单例对象");
    }
}

// 获取单例实例
const s1 = SingleDog.getInstance();
const s2 = SingleDog.getInstance();

console.log(s1 === s2); // 输出: true

因为但是内部函数引用了getInstance()外部函数的变量instance,那么instance变量依旧会被保存在内层中,所以我们可以通过判断instance是否为空来获得地址。

总结

单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点来访问这个唯一的实例。单例模式通常用于控制对资源的访问,例如配置管理、日志记录、数据库连接等。

今天的内容就到这啦,如果你觉得小编写的还不错的话,或者对你有所启发,请给小编一个辛苦的赞吧

相关推荐
摸鱼仙人~18 分钟前
styled-components:现代React样式解决方案
前端·react.js·前端框架
sasaraku.1 小时前
serviceWorker缓存资源
前端
RadiumAg2 小时前
记一道有趣的面试题
前端·javascript
yangzhi_emo2 小时前
ES6笔记2
开发语言·前端·javascript
yanlele2 小时前
我用爬虫抓取了 25 年 5 月掘金热门面试文章
前端·javascript·面试
中微子3 小时前
React状态管理最佳实践
前端
烛阴4 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
小兵张健4 小时前
武汉拿下 23k offer 经历
java·面试·ai编程
中微子4 小时前
JavaScript 事件与 React 合成事件完全指南:从入门到精通
前端
Hexene...4 小时前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts