0

0

javascript设计模式有哪些_如何用单例模式创建唯一对象?

狼影

狼影

发布时间:2026-01-09 20:01:02

|

261人浏览过

|

来源于php中文网

原创

单例模式的本质是逻辑约束而非语法限制,确保类在整个应用生命周期中仅初始化一次且返回同一实例;适用于配置管理、日志器等跨模块共享组件,不适用于需多实例的场景。

javascript设计模式有哪些_如何用单例模式创建唯一对象?

单例模式的核心判断:是否真需要全局唯一实例?

JavaScript 里 new 一个对象、用字面量 {}Object.create(null) 都能快速创建对象,但“单例”不是语法限制,而是逻辑约束:确保整个应用生命周期中,某个类最多被初始化一次,且所有调用都返回同一个实例。别为了设计模式而单例——比如配置管理、日志器、状态仓库这类跨模块共享且无状态/轻状态的组件才适合;频繁创建不同参数的实例(如用户卡片、API 请求封装)硬套单例反而导致耦合和难以测试。

最简可行的单例实现:闭包 + 静态属性

ES6+ 环境下,用类配合静态属性是最直观的方式。关键点在于:实例缓存在类自身上,构造函数不直接暴露,而是通过静态方法控制创建时机。

class Logger {
  constructor() {
    if (Logger.instance) {
      return Logger.instance;
    }
    this.logs = [];
    Logger.instance = this;
  }

  static getInstance() {
    return Logger.instance || new Logger();
  }

  log(msg) {
    this.logs.push(`${new Date().toISOString()}: ${msg}`);
  }
}

// 使用
const a = Logger.getInstance();
const b = Logger.getInstance();
console.log(a === b); // true

注意:Logger.instance 是手动维护的引用,如果误删或重赋值(如 Logger.instance = null),下次调用 getInstance() 会新建实例,破坏单例性。生产环境建议加 Object.freeze(Logger) 锁定构造函数本身。

更健壮的写法:利用 Symbol 防止外部篡改

Symbol 作私有键名,避免 instance 被意外覆盖。同时把初始化逻辑收进静态 getter,让调用更自然。

立即学习Java免费学习笔记(深入)”;

Glimmer Ai
Glimmer Ai

基于GPT-3和DALL·E2的PPT制作工具

下载
class Database {
  constructor() {
    if (Database[Database.instanceSymbol]) {
      return Database[Database.instanceSymbol];
    }
    this.connection = 'fake-connection-string';
    Database[Database.instanceSymbol] = this;
  }

  static get instanceSymbol() {
    if (!Database._instanceSymbol) {
      Database._instanceSymbol = Symbol('db-instance');
    }
    return Database._instanceSymbol;
  }

  static get instance() {
    return Database[Database.instanceSymbol] || new Database();
  }
}

// 使用
const db1 = Database.instance;
const db2 = Database.instance;
console.log(db1 === db2); // true

这个版本的关键差异:

  • Symbol 键无法被 for...inObject.keys() 枚举,外部代码几乎无法干扰
  • 静态 get instance() 语法比 getInstance() 更符合直觉,也避免忘记加括号
  • 仍需注意:若模块被多次 import(如在不同打包上下文),每个导入副本会拥有独立的 Symbol 和静态属性,此时单例失效——这是模块系统层面的问题,不是单例逻辑缺陷

常见陷阱:懒加载 vs 构造时副作用

上面例子都是“懒加载”:第一次调用时才初始化。但如果你的单例构造函数里有副作用(如发起网络请求、绑定全局事件、修改 DOM),要格外小心:

  • 如果多个模块几乎同时调用 getInstance(),可能触发多次构造(因检查和赋值非原子操作)
  • 异步初始化(如 await initDB())会让单例变成“伪单例”:返回的是 Promise,而非实例本身
  • 服务端渲染(SSR)中,单例在 Node.js 进程内共享,多个请求共用同一实例,容易引发状态污染

真正安全的异步单例需要双重检查 + Promise 缓存,且必须明确文档化其线程/请求隔离边界。多数场景下,宁可把初始化拆到启动阶段(如 initApp()),也不在 getInstance 里埋异步逻辑。

单例最难的不是写法,是厘清“唯一”的作用域——是当前 JS 执行上下文?当前模块导入链?还是整个浏览器 Tab?没想清楚这点,代码越“规范”,问题越隐蔽。

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

WorkBuddy
WorkBuddy

腾讯云推出的AI原生桌面智能体工作台

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
es6新特性
es6新特性

es6新特性有:1、块级作用域变量;2、箭头函数;3、模板字符串;4、解构赋值;5、默认参数;6、 扩展运算符;7、 类和继承;8、Promise。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

106

2023.07.17

es6新特性有哪些
es6新特性有哪些

es6的新特性有:1、块级作用域;2、箭头函数;3、解构赋值;4、默认参数;5、扩展运算符;6、模板字符串;7、类和模块;8、迭代器和生成器;9、Promise对象;10、模块化导入和导出等等。本专题为大家提供es6新特性的相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.08.04

JavaScript ES6新特性
JavaScript ES6新特性

ES6是JavaScript的根本性升级,引入let/const实现块级作用域、箭头函数解决this绑定问题、解构赋值与模板字符串简化数据处理、对象简写与模块化提升代码可读性与组织性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

233

2025.12.24

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

254

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

1089

2024.03.01

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

765

2023.08.10

go语言闭包相关教程大全
go语言闭包相关教程大全

本专题整合了go语言闭包相关数据,阅读专题下面的文章了解更多相关内容。

152

2025.07.29

js正则表达式
js正则表达式

php中文网为大家提供各种js正则表达式语法大全以及各种js正则表达式使用的方法,还有更多js正则表达式的相关文章、相关下载、相关课程,供大家免费下载体验。

531

2023.06.20

C# ASP.NET Core微服务架构与API网关实践
C# ASP.NET Core微服务架构与API网关实践

本专题围绕 C# 在现代后端架构中的微服务实践展开,系统讲解基于 ASP.NET Core 构建可扩展服务体系的核心方法。内容涵盖服务拆分策略、RESTful API 设计、服务间通信、API 网关统一入口管理以及服务治理机制。通过真实项目案例,帮助开发者掌握构建高可用微服务系统的关键技术,提高系统的可扩展性与维护效率。

76

2026.03.11

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 6万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 3.4万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号