javascript中用闭包实现单例模式的核心是利用闭包保存私有实例变量,对外仅暴露一个获取实例的函数,确保多次调用返回同一对象;通过立即执行函数封装let声明的instance变量,首次调用创建、后续直接返回,实现懒加载与唯一性。

JavaScript 中用闭包实现单例模式,核心是利用闭包保存私有实例变量,对外只暴露一个获取实例的函数,确保多次调用返回同一个对象。
闭包封装私有实例
把实例变量声明在闭包作用域内(如立即执行函数中),外部无法直接访问或修改它,只能通过返回的函数间接操作。
- 用 let 或 const 声明实例变量,避免全局污染
- 闭包内部判断实例是否存在,不存在则创建,存在则直接返回
- 返回的工厂函数是唯一入口,保证“懒加载”和“只创建一次”
基础实现示例
以下是一个简洁可靠的写法:
const Singleton = (function() {
let instance = null;
function createInstance() {
return {
name: 'Singleton Instance',
getTime: () => new Date().toISOString()
};
}
return function getInstance() {
if (!instance) {
instance = createInstance();
}
return instance;
};
})();
// 使用
const a = Singleton();
const b = Singleton();
console.log(a === b); // true
支持构造函数与参数的增强版
若需初始化参数(如配置项),可在首次调用时传入,后续忽略;也可设计成“首次传参有效”,其余调用不覆盖。
- 首次调用 getInstance(config) 时创建并缓存实例
- 后续调用即使传参也不影响已有实例,保持单例语义
- 可结合 class 使用,让逻辑更清晰、可扩展
注意事项与常见误区
闭包单例不是万能的,要注意运行环境和生命周期:
- 模块打包后可能被 tree-shaking 影响,确保导出的是函数而非实例
- 服务端(如 Node.js)中每个模块加载都是独立作用域,同一文件多次 require 仍为单例;跨文件需统一导入路径
- 不要在闭包外修改 instance,否则破坏单例性;所有状态变更应通过实例方法进行
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











