JavaScript 单例模式详解:字面量、类与工厂实现

作者:代码拾荒

时间:2026-10-23

浏览:579

本文深入解析 JavaScript 中的单例模式,涵盖创建型设计模式的核心概念。通过字面量、类封装及工厂方法三种方式展示具体实现,重点讲解 new 关键字在单例中的行为特性及不可变对象的应用,帮助开发者掌握控制全局状态的最佳实践。

文章目录

本文详细解析 JavaScript 设计模式中的单例模式,包括其定义与多种实现方式,供开发者参考学习。

优秀的设计模式能显著提升代码可读性,降低系统复杂度与维护成本。笔者计划通过系列文章,通俗讲解常见且实用的设计模式。

本次从最基础的模式开始:单例模式。

示例代码采用 ES6 语法编写,旨在简化非核心细节。

概念

单例模式(Singleton)归类为创建型设计模式,其核心在于限制只能创建单一对象或某个类的唯一实例。

通常使用该模式旨在控制整个应用程序的状态。在实际开发中,常见的单例应用包括:Vuex 中的 Store、Vue 的根实例,以及导出单个对象的 ES6 模块等。

字面量写法

最基础的单例实现形式如下所示。


const cat = {
  name: 'mi',
  age: 4
}

熟悉 const 语法的开发者应当知晓,该对象本身不可被重新赋值,但其内部属性依然可变。

若需创建不可变的单例对象,可采用以下方案。


const cat = {
  name: 'mi',
  age: 4
}

Object.freeze(cat);

此时无法新增或修改该对象上的任何属性,使其成为真正的“冻结”对象。

若在模块中使用上述写法,虽不会污染全局作用域,但直接生成固定对象的方式缺乏足够的灵活性。

常用写法

相比之下,使用类或工厂方法实现单例更为常见。假设存在一个名为 Logger 的类,其具备与 Console 相同的 API。

类单例

类的单例写法应用广泛,若期望按如下方式使用:


const logger = new Logger();
logger.log('msg');

// 这里大概写了 1000 行代码

const logger2 = new Logger();
logger.log('new msg');

logger === logger2; // true

即使多次 new Logger,返回的始终是同一个实例。

接下来直接展示最实用的实现方式。


class Logger {
  constructor () {
    if (!Logger._singleton) {
      Logger._singleton = this;
    }
    return Logger._singleton;
  }
  
  log (...args) {
    console.log(...args);
  }
}

export default Logger;

上述实现将单例对象存储于构造器上,因此无论 new Logger 多少次,返回的均为同一个 Logger 实例。

此处需注意一个细节:若 new 关键字后的构造函数显式返回一个对象,new 表达式将返回该对象而非新实例。

具体原理可参考《你不知道的 JavaScript(上卷)》中关于 new 绑定的章节。

工厂单例

若不使用 new 关键字,可通过工厂方法返回单例对象。


let logger = null

class Logger {
  log (...args) {
    console.log(...args);
  }
}

function createLogger() {
  if (!logger) {
    logger = new Logger();
  }
  return logger;
}

export default createLogger;

上述代码相当于在模块内部缓存了 logger 实例,并导出一个工厂方法。这种写法在模块化代码中较为常见,工厂方法亦可接收参数以初始化单例对象。

今日内容易于理解,其中介绍的单例写法也是笔者常用的方案。

下一篇将具体讲解工厂模式的应用。

参考内容

  • 《JavaScript 设计模式》
  • 《JavaScript 面向对象编程指南》
  • 《你不知道的 JavaScript(上卷)》
  • Working with Singletons in JavaScript

感兴趣的朋友可使用在线 HTML/CSS/JavaScript 代码运行工具:http://tools.jb51.net/code/HtmlJsRun 测试上述代码运行效果。

更多关于 JavaScript 相关内容感兴趣的读者可查看本站专题:《javascript 面向对象入门教程》、《JavaScript 错误与调试技巧总结》、《JavaScript 数据结构与算法技巧总结》、《JavaScript 遍历算法与技巧总结》及《JavaScript 数学运算用法总结》

希望本文所述对大家 JavaScript 程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章