JavaScript单例模式:原理、实现与多线程场景分析

作者:青柠

时间:2026-10-24

浏览:563

本文深入解析JavaScript中的单例模式,涵盖其定义、应用场景及核心实现方式。详细对比了饿汉式与懒汉式两种分支的优缺点,并探讨了在JavaScript单线程环境下多线程并发对实例唯一性的影响。通过代码示例说明如何严格控制实例访问以节约系统资源,同时指出单例模式在扩展性和职责单一性方面的潜在局限。

文章目录

单例模式概述

本文详细解析了JavaScript中的单例模式,旨在为开发者提供实用的参考与指导。

单例模式是结构最为简洁的设计模式之一,专门用于确保软件系统中某个类仅存在一个实例。这是一种简单却极具实用价值的模式。

单例模式的定义在于确保一个类只有一个实例,并提供全局访问点。该类自行创建实例并供整个系统使用,属于对象创建型模式。

场景:日常编码中会有很多需要重用的场景,例如弹窗,键盘输入这类公共组件,我们往往希望它只创建一次,在第二次使用时重复使用之前创建好的实例。为了节约资源,提高性能,需要保证实例对象的唯一性,就可以采用单例模式实现。使用单例模式要注意:1.某个类只能有一个实例 2.它必须自行创建这个实例 3.它必须自行向整个系统提供这个实例

单例模式实现与对比

以下通过具体示例展示单例模式的实现方式。

单例模式主要包含两种实现分支:饿汉式单例和懒汉式单例。下面将对比两者的具体区别。


//懒汉模式单例demo
//懒汉模式:只有在我需要实例的时候才会第一次实例化,只有当我第一次调用getInstance时才会去执行init获取实例。
var Singleton = (function () {
  var instantiated; 
  function init(){
    return {
      sayHello: function () {
        console.log('hello');
      }
    };
  }
 
  return {
    getInstance: function () {
      if(!instantiated){
        instantiated = init();
      }
      return instantiated;
    } 
  }
})();
 
//只能通过getInstance方法获取对象实例:
var instance = Singleton.getInstance();
var instance2 = Singleton.getInstance();
instance.sayHello(); //hello
instance2.sayHello(); //hello
console.log(instance === instance2); //true
 
//饿汉模式demo
//饿汉模式:在类初始化时就立刻执行getInstance进行赋值。
var Singleton = (function () {
  var instantiated = init();  //初始化时即对instantiated进行赋值
  function init(){
    return {
      sayHello: function () {
 console.log('hello');
   }
 };
  }
 
  return {
 getInstance: function () {
   return instantiated;
 } 
  }
})();
 
var instance = Singleton.getInstance();
var instance2 = Singleton.getInstance();
instance.sayHello(); //hello
instance2.sayHello(); //hello
console.log(instance === instance2); //true

上述代码示例引发一个思考:如果init函数执行耗时较长,是否还能保证类只有一个实例?

在多线程环境中,若init函数执行期间再次触发getInstance调用,可能导致生成多个实例。然而,JavaScript作为单线程语言,是否会出现此类问题?

对比两种模式:饿汉式在启动时即完成实例化,在资源利用效率上稍显不足;懒汉式虽延迟加载,但在多线程场景下需特别注意并发初始化带来的潜在风险。

单例模式优缺点与适用场景

对单例模式进行总结。

优点包括:严格控制实例的访问权限;节约系统性能,避免重复创建和销毁对象,从而减少资源浪费。

缺点在于:扩展单例模式必须修改类主体,这与开闭原则相冲突;此外,单例模式职责过重,既包含业务逻辑又负责对象创建,一定程度上违背了单一职责原则,存在功能耦合。

适用场景包括:系统仅需一个实例对象;客户调用类的单个实例时,仅允许通过唯一的公共访问点获取,禁止其他途径访问该实例。

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容感兴趣的读者可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章