JavaScript函数表达式实现惰性单例构造器,通过IIFE创建闭包缓存instance,首次调用才初始化并返回同一实例,支持私有状态、避免全局污染且兼容性优于class静态属性方式。

JavaScript 中函数表达式常用于实现“惰性单例构造器”,核心在于把实例缓存逻辑封装在闭包内,避免污染全局、支持私有变量,并做到首次调用才初始化。
闭包 + 惰性初始化
用立即执行的函数表达式(IIFE)创建私有作用域,内部维护一个 instance 变量。返回的工厂函数每次被调用时检查该变量,未创建则 new 实例并缓存,否则直接返回缓存值。
- 实例只在第一次调用时生成,节省资源
- 构造逻辑、私有状态(如配置、计数器)可安全隐藏在闭包中
- 外部无法绕过该函数直接 new,天然规避重复实例化
返回统一构造器函数
函数表达式本身可作为“单例构造器”暴露给使用者——它看起来像普通函数,但行为是受控的:
- 调用 createLogger() 多次,始终返回同一对象引用
- 构造参数仅在首次生效(如初始化配置),后续调用忽略参数
- 适合封装需要初始化但又不希望每次新建的类,比如日志器、配置管理器、WebSocket 连接器
与 class 静态属性方式的区别
相比 class Logger { constructor() { if (Logger.instance) return Logger.instance; … }} 这种写法:
立即学习“Java免费学习笔记(深入)”;
- 函数表达式方式不依赖类或静态属性,兼容性更好(ES3+ 即可用)
- 没有暴露 Logger.instance 这样的公共属性,不易被误删或篡改
- 闭包天然隔离实例状态,无需靠开发者自觉维护“不可删”约定
典型写法示例
以下是一个带私有状态和惰性初始化的函数表达式单例构造器:
const createDBConnection = (function () {
let instance;
function Connection(config) {
this.host = config.host;
this.port = config.port || 3306;
this._connectedAt = Date.now(); // 私有字段,外部不可访问
}
Connection.prototype.query = function (sql) {
return `executed: ${sql} at ${this._connectedAt}`;
};
return function (config) {
if (!instance) {
instance = new Connection(config);
}
return instance;
};
})();
<p>// 使用
const db1 = createDBConnection({ host: 'localhost' });
const db2 = createDBConnection({ host: '127.0.0.1', port: 5432 });
console.log(db1 === db2); // true
console.log(db1.query('SELECT <em> FROM users')); // executed: SELECT </em> FROM users at 1719193200000
文章来自机圈观察员网,发布者:,转载请注明出处:https://www.jqgcy.com/jiquanzatan/123669.html