Javascript单例设计模式

Javascript单例设计模式
最新回答
夏迟归

2026-10-22 16:15:49

JavaScript单例设计模式的核心在于确保一个类只有一个实例,并提供全局访问点。 在您提供的代码示例中,MySingleton 类通过闭包变量 instance 和构造函数内的逻辑实现了单例模式。以下是详细解析:

1. 单例模式的实现原理
  • 闭包变量 instance:在模块作用域中声明 let instance,用于存储类的唯一实例。由于它在类外部定义,但被构造函数访问,形成了闭包,确保实例的唯一性。

  • 构造函数逻辑:

    constructor() { if (!instance) { this.publicProperty = 'I am also public'; instance = this; // 首次实例化时赋值 } return instance; // 后续实例化直接返回已有实例}

    第一次调用 new MySingleton() 时,instance 为 undefined,会执行初始化逻辑并赋值 instance = this。

    后续调用 new MySingleton() 时,构造函数直接返回已存储的 instance,不再创建新对象。

2. 验证单例行为
  • 共享属性和方法:所有实例(如 singleA 和 singleB)实际指向同一个对象,因此它们的属性和方法完全相同:

    const singleA = new MySingleton();const singleB = new MySingleton();console.log(singleA === singleB); // true(严格相等)
  • 私有成员与随机数验证:

    privateMethod 和 privateVariable 是模块级的私有成员,仅通过类方法间接访问(如 getRandomNumber 返回闭包中的 randomNumber)。

    由于 randomNumber 在模块加载时生成且仅一次,所有实例的 getRandomNumber() 返回相同值:

    console.log(singleA.getRandomNumber() === singleB.getRandomNumber()); // true
3. 单例模式的典型应用场景
  • 全局配置管理:如应用主题、用户登录状态等需唯一共享的数据。
  • 资源密集型对象:如数据库连接池,避免重复创建。
  • 日志记录器:确保日志统一写入同一来源。
4. 潜在问题与改进
  • 透明性:当前实现需用户主动调用 new,可能误导为普通类。可通过静态方法优化:class MySingleton { static getInstance() { if (!instance) instance = new MySingleton(); return instance; } // ...其他方法}// 使用方式:const instance = MySingleton.getInstance();
  • 线程安全:JavaScript 单线程特性无需考虑并发问题,但在多环境(如服务端 Node.js 的集群模式)需额外处理。
5. 完整代码示例let instance;const randomNumber = Math.random();class MySingleton { constructor() { if (!instance) { this.publicProperty = 'I am also public'; instance = this; } return instance; } publicMethod() { console.log('The public can see me!'); } getRandomNumber() { return randomNumber; }}// 导出单例类export default MySingleton;// 使用验证const singleA = new MySingleton();const singleB = new MySingleton();console.log(singleA.getRandomNumber() === singleB.getRandomNumber()); // trueconsole.log(singleA === singleB); // true

总结:单例模式通过控制实例的创建过程,确保全局唯一性。您的实现正确展示了这一特性,尤其通过闭包和构造函数逻辑保证了实例的唯一性及私有成员的封装。