js 实现单例模式
使用闭包实现单例模式
闭包可以封装私有变量,确保实例唯一性。通过立即执行函数返回一个获取实例的方法,首次调用时创建实例,后续调用直接返回已创建的实例。
const Singleton = (function() {
let instance;
function createInstance() {
const object = new Object("I am the instance");
return object;
}
return {
getInstance: function() {
if (!instance) {
instance = createInstance();
}
return instance;
}
};
})();
const instance1 = Singleton.getInstance();
const instance2 = Singleton.getInstance();
console.log(instance1 === instance2); // true
使用 ES6 Class 实现单例
通过静态属性和方法控制实例化过程。静态属性存储唯一实例,静态方法负责实例的创建和返回。
class Singleton {
static instance;
constructor() {
if (Singleton.instance) {
return Singleton.instance;
}
Singleton.instance = this;
}
}
const obj1 = new Singleton();
const obj2 = new Singleton();
console.log(obj1 === obj2); // true
使用模块特性实现单例
ES6 模块系统天然支持单例模式。模块在第一次被导入时会被缓存,后续导入都会返回同一个实例。
// singleton.js
let instance;
export default class Singleton {
constructor() {
if (instance) {
return instance;
}
instance = this;
}
}
// 使用方式
import Singleton from './singleton.js';
const a = new Singleton();
const b = new Singleton();
console.log(a === b); // true
惰性单例实现
延迟实例化直到真正需要时,适用于资源消耗较大的对象。通过代理模式实现按需创建。
class HeavyResource {
constructor() {
console.log('HeavyResource initialized');
}
}
const LazySingleton = (function() {
let instance;
return {
getInstance: function() {
if (!instance) {
instance = new HeavyResource();
}
return instance;
}
};
})();
// 只有调用时才初始化
const resource = LazySingleton.getInstance();
线程安全的单例实现
虽然 JavaScript 是单线程语言,但异步场景下也需要考虑并发问题。使用立即初始化的方式避免竞争条件。
const ThreadSafeSingleton = new (function() {
const instance = this;
this.getInstance = function() {
return instance;
};
})();
// 任何时候调用都返回同一实例
const safeInstance = ThreadSafeSingleton.getInstance();
每种实现方式适用于不同场景,闭包方式兼容性好,ES6 Class 语法更清晰,模块方式最简洁。根据具体需求选择合适的方法,注意考虑惰性加载、线程安全等额外需求。







