闭包实现单例的核心逻辑是利用函数作用域封存私有变量instance,首次调用getinstance时创建并缓存实例,后续调用直接返回该引用,确保全局唯一且不可篡改。

闭包实现单例的核心逻辑
闭包实现单例,本质是利用函数作用域“封存”一个私有变量(如 instance),让它不被外部重置或覆盖。每次调用获取实例的方法时,先检查该变量是否存在;不存在就新建并赋值,存在则直接返回——这样无论调用多少次,都只创建一次对象,且所有调用共享同一引用。
标准写法:IIFE + getInstance 方法
这是最稳定、兼容性最好的方式,适用于所有 ES5+ 环境:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用立即执行函数(IIFE)包裹私有状态,避免污染全局
- 内部声明 let instance = null,作为唯一实例的缓存容器
- 暴露一个 getInstance 方法作为统一入口,内部做存在性判断
- 构造逻辑(如 new XXX() 或对象字面量)只在首次调用时执行
关键细节不能漏
真正保证“唯一性”的不是语法限制,而是执行流程控制:
-
不能导出构造函数本身,否则用户仍可
new Singleton()多次——必须隐藏构造过程 - instance 必须在闭包内定义,若放在全局或模块顶层,可能被其他代码意外修改
-
getInstance 返回的是引用,不是新拷贝,所以
obj1 === obj2恒为 true - 如果需要支持参数化初始化(如传入配置),应在第一次调用时接收并缓存,后续调用忽略参数或抛错
为什么比 class 静态属性更稳妥?
ES6 class 的静态属性方式(如 static instance)语义清晰,但存在隐患:
- 静态属性可被外部直接赋值覆盖:
MySingleton.instance = {} - 模块热更新或多次 import 可能导致重复初始化(尤其在某些打包工具中)
- 闭包方案天然隔离,instance 完全不可见、不可写,安全性更高
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










