前端单例对象实现

前言

最近在开发个人项目的过程中,涉及到一个场景需要创建一个单例对象(即只能实例化一次,后续无论如何实例化获取的都是最初实例化的对象)
但是js实现单例对象的时候始终有缺陷,即便是基于模块导出了一个已实例化完成的对象。也一样可以通过原型链的方式去获取单例对象的class。

因此在实现这个功能的过程中,我花了不少时间,下面讲一下我的单例对象的实现思路。

实现思路

在之前实现minivue3的过程中我频繁的使用到了proxy这个代理。
因此从中我获得灵感,我希望同样基于模块,我默认导出一个proxy对象,对象劫持的是目标class(class也是对象,js万物皆对象,构造函数只是其中一个熟悉),并在proxy对象中监听构造函数。
在实例化我们导出的proxy对象中,实际上会触发我们监听的构造函数。

如下所示:

在构造函数被触发的时候,可以返回已经实例化好的对象,这样无论怎么new 拿到的都是我们最初已经实例化完的对象。

代码实现

因此代码实现很简单

js 复制代码
// 封装proxy代理单例函数
function singleton(className) {
  let obj = '' // 通过闭包存储实例化的对象
  return new Proxy(className, {
    construct: function(target, args) {
      if(!obj) obj = new target(...args)
      return obj
    },
  });
}

使用时默认导出封装之后的单例函数即可,附上用例如下:

js 复制代码
// 目标对象
class student {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

// 封装学生单例
let singletonStu = singleton(student)

// 测试用例
let c = new singletonStu('xiaoShan', 20)
let d = new singletonStu('jiajia', 19)
console.log(c === d)

效果如下:

总结

如果朋友们以后有遇到这种单例的情况不妨通过这种代理和模块结合的方式去实现,效果还是不错的。但需要留意proxy对象有可能在一些古早浏览器中不兼容,今天就分享到这里。

相关推荐
Y38153266211 分钟前
SERP API 请求体 Gzip 压缩优化实战:大数据量降带宽 80%
开发语言·前端·php
踩着两条虫1 小时前
VTJ.PRO AI Agent 技术白皮书
前端·vue.js·低代码
子兮曰1 小时前
解剖 Claude Code:从入口架构逆向工程看 AI 编程工具的信任边界设计
前端·后端·claude
先吃饱再说1 小时前
层层传递太“痛”了:useContext 给 React 组件装了个“无线遥控器”
前端·react.js·前端框架
颜进强1 小时前
前端看后端 15:什么是 DNS?
前端·后端·ai编程
文艺理科生1 小时前
LangChain.js-v1-记忆管理最佳实践
前端·javascript·后端
子兮曰2 小时前
Elysia vs Hono 完整性能对比:Bun 专属优化还是跨平台通用,2026 实测数据给出的答案
前端·后端·typescript
To_OC2 小时前
从一个颜色选择器说起:我终于整明白了 React+TS 里的 model 与 api 分层
前端·react.js·typescript
赵大仁2 小时前
浏览器端 RAG:Transformers.js + WebGPU 本地检索入门
前端·ai·react·webgpu·rag
木叶丸2 小时前
从 Loop 到 Graph:AI 智能体协作系统工程指南
前端·后端·架构