javascript设计模式有哪些_如何实现一个简单的单例模式?

发布时间 - 2025-12-29 00:00:00    点击率:
单例模式确保一个类只有一个实例并提供全局访问点,核心是控制创建时机、防止重复初始化、保证多次调用返回同一对象;常用实现包括闭包缓存、ES6 class 静态属性及惰性安全的私有静态属性方式。

JavaScript 中常用的设计模式包括单例模式、工厂模式、观察者模式(发布-订阅)、策略模式、代理模式、装饰器模式、适配器模式、命令模式、状态模式等。其中单例模式最常用于管理全局唯一实例,比如配置管理器、日志记录器、弹窗控制器等。

单例模式的核心要点

单例模式确保一个类只有一个实例,并提供一个全局访问点。关键在于:控制实例的创建时机、防止重复初始化、保证多次调用返回同一对象。

基础实现:使用闭包和变量缓存

这是最简洁、易理解的方式,利用立即执行函数封装私有变量,避免污染全局作用域:

const Singleton = (function() {
  let instance = null;

function createInstance() { return { name: 'Singleton Instance', getId: () => Math.random().toString(36).substr(2, 9) }; }

return { getInstance: function() { if (!instance) { instance = createInstance(); } return instance; } }; })();

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

ES6 Class + 静态属性方式(更现代)

借助 class 语法和静态属性,语义更清晰,也便于扩展:

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

log(message) { this.logs.push([${new Date().toISOString()}] ${message}); }

getLogCount() { return this.logs.length; } }

// 手动初始化一次(或在首次调用时惰性初始化) Logger.instance = null;

// 使用 const logger1 = new Logger(); const logger2 = new Logger(); console.log(logger1 === logger2); // true

惰性安全的 Class 单例(推荐)

把实例创建逻辑完全封装在类内部,外部无需关心初始化细节:

class DatabaseConnection {
  static #instance = null;

constructor() { if (DatabaseConnection.#instance) { return DatabaseConnection.#instance; } this.connectionId = conn_${Date.now()}_${Math.random().toFixed(4)}; DatabaseConnection.#instance = this; }

static getInstance() { if (!DatabaseConnection.#instance) { DatabaseConnection.#instance = new DatabaseConnection(); } return DatabaseConnection.#instance; }

query(sql) { console.log(Executing: ${sql} on ${this.connectionId}); } }

// 使用 const db1 = DatabaseConnection.getInstance(); const db2 = DatabaseConnection.getInstance(); console.log(db1 === db2); // true db1.query('SELECT * FROM users');

注意事项与常见误区

  • 避免直接 new 多次——必须通过 getInstance 或静态方法获取实例
  • 构造函数内不能做耗时或副作用操作(如发起网络请求),除非明确需要且已做惰性处理
  • 如果涉及异步初始化(如加载配置),需配合 Promise 和状态标记,不能简单用 if 判断
  • 单例不是万能的,过度使用会增加模块耦合,测试困难;优先考虑依赖注入

不复杂但容易忽略


# javascript  # es6  # java  # 作用域 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Bootstrap整体框架之CSS12栅格系统  新三国志曹操传主线渭水交兵攻略  如何有效防御Web建站篡改攻击?  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  Laravel如何实现API版本控制_Laravel API版本化路由设计策略  香港服务器网站测试全流程:性能评估、SEO加载与移动适配优化  如何用美橙互联一键搭建多站合一网站?  Midjourney怎样加参数调细节_Midjourney参数调整技巧【指南】  魔毅自助建站系统:模板定制与SEO优化一键生成指南  Laravel模型关联查询教程_Laravel Eloquent一对多关联写法  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  UC浏览器如何设置启动页 UC浏览器启动页设置方法  Windows10怎样连接蓝牙设备_Windows10蓝牙连接步骤【教程】  电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?  重庆市网站制作公司,重庆招聘网站哪个好?  如何快速搭建高效WAP手机网站吸引移动用户?  深圳网站制作的公司有哪些,dido官方网站?  linux top下的 minerd 木马清除方法  Laravel PHP版本要求一览_Laravel各版本环境要求对照  ,网页ppt怎么弄成自己的ppt?  如何实现javascript表单验证_正则表达式有哪些实用技巧  高防服务器:AI智能防御DDoS攻击与数据安全保障  Laravel怎么处理异常_Laravel自定义异常处理与错误页面教程  如何在建站之星绑定自定义域名?  公司门户网站制作流程,华为官网怎么做?  Laravel如何实现数据库事务?(DB Facade示例)  Laravel如何升级到最新的版本_Laravel版本升级流程与兼容性处理  html5audio标签播放结束怎么触发事件_onended回调方法【教程】  太平洋网站制作公司,网络用语太平洋是什么意思?  PHP的CURL方法curl_setopt()函数案例介绍(抓取网页,POST数据)  ChatGPT回答中断怎么办 引导AI继续输出完整内容的方法  如何快速搭建高效WAP手机网站?  网站页面设计需要考虑到这些问题  Python文本处理实践_日志清洗解析【指导】  深入理解Android中的xmlns:tools属性  laravel服务容器和依赖注入怎么理解_laravel服务容器与依赖注入解析  如何用VPS主机快速搭建个人网站?  JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)  香港服务器选型指南:免备案配置与高效建站方案解析  Laravel如何使用查询构建器?(Query Builder高级用法)  清除minerd进程的简单方法  android nfc常用标签读取总结  Laravel如何集成Inertia.js与Vue/React?(安装配置)  Laravel怎么实现API接口鉴权_Laravel Sanctum令牌生成与请求验证【教程】  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  Laravel如何与Inertia.js和Vue/React构建现代单页应用  Laravel怎么实现模型属性转换Casting_Laravel自动将JSON字段转为数组【技巧】  浅谈redis在项目中的应用  标题:Vue + Vuex + JWT 身份认证的正确实践与常见误区解析  Python文件流缓冲机制_IO性能解析【教程】