JavaScript 单例模式实现唯一模态框

作者:拾光时间:2026-10-22 07:48:58浏览:186

本文详解 JavaScript 中单例模式的应用,通过静态方法与闭包两种方案控制实例创建,解决模态框重复生成问题。对比传统面向对象方式,展示如何利用闭包特性确保全局仅存在一个模态框实例,提升页面性能与用户体验。

单例模式核心概念

单例模式的核心概念是什么?

“单”代表唯一,“例”指代实例化后的对象。该模式旨在确保一个构造函数仅能生成一个实例。理解并掌握单例模式具有重要意义,其应用场景广泛,例如网站中频繁点击弹出的模态框,无论用户操作多少次,系统应只创建并显示一个实例;又如后台数据库连接池,通常也维持单一连接以优化资源。本文聚焦于单例模式在模态框中的具体应用,首要任务是厘清如何实现单例逻辑。

常规构造函数方式分析

首先回顾常规的构造函数结合原型链的实现方式,这是 JavaScript 中常见的对象创建范式。


function Singleton ( uName ){
   this.userName = uName;
   this.ins = null;
  }
  Singleton.prototype.showUserName = function(){
   return this.userName;
  }
  var obj1 = new Singleton( 'ghostwu' );
  var obj2 = new Singleton( 'ghostwu2' );
  console.log( obj1 === obj2 ); //false

在常规模式下,每次执行 new 操作都会在内存中开辟新的空间以存储新实例,这导致无法保证全局唯一性。因此,若要实现单例,必须对 new 创建实例的过程进行严格控制。关键在于限制用户直接调用构造函数,转而采用其他机制来管理实例的生成。

静态方法实现单例

第一种实现策略:在构造函数内部定义静态方法,以此掌控实例的创建流程。


function Singleton ( uName ){
   this.userName = uName;
  }
  Singleton.prototype.showUserName = function(){
   return this.userName;
  }
  Singleton.getInstance = function( uName ){
   if ( !this.ins ) {
    this.ins = new Singleton( uName );
   }
   return this.ins;
  }

  var obj1 = Singleton.getInstance( 'ghostwu' );
  var obj2 = Singleton.getInstance( 'ghostwu2' );
  console.log( obj1 === obj2 ); //true

如代码第 8 行所示,逻辑判断变量 ins 是否已保存实例。若未保存,则执行 new 操作创建新实例;若已存在,则直接返回现有实例。当第二次调用时,因 ins 已存在,直接返回该对象而无需再次 new,从而确保全局仅有一个实例。

闭包与立即执行函数实现

第二种实现策略:借助闭包与立即执行函数表达式(IIFE)的特性来实现。


function Singleton ( uName ){
   this.userName = uName;
  }
  Singleton.prototype.showUserName = function(){
   return this.userName;
  }
  Singleton.getInstance = (function(){
   var ins = null;
   return function( uName ) {
    if ( !ins ) {
     ins = new Singleton( uName );
    }
    return this;
   }
  })();

  var obj1 = Singleton.getInstance( 'ghostwu' );
  var obj2 = Singleton.getInstance( 'ghostwu2' );
  console.log( obj1 === obj2 );

上述两种方案均能有效实现单例。接下来,本文将选用第二种方法(闭包方案)来构建一个唯一的模态框。

传统模态框实现缺陷

三、传统面向对象方式:每次点击均生成新的模态框

相关样式定义如下:


div {
   width: 200px;
   height: 200px;
   border:1px solid #09f;
   box-shadow: 2px 2px 1px #666;
   position: absolute;
  }

HTML 结构部分:


<input type="button" value="弹窗">

JavaScript 逻辑部分:


var oBtn = document.querySelector("input"),
   offset = 20, index = 1;
  function Module( pos ){
   this.offset = pos || 20;
  }
  Module.prototype.create = function(){
   var oDiv = document.createElement( "div" );
   oDiv.style.left = ( ++index ) * offset + 'px';
   oDiv.style.top = ( ++index ) * offset + 'px';
   oDiv.innerHTML = 'ghostwu教你用设计模式实战';
   return oDiv;
  }
  oBtn.onclick = function(){
   var oDiv = new Module();
   document.body.appendChild( oDiv.create() );
  }

单例模式核心概念

单例模式改造模态框

四、使用单例模式进行改造

改造后的 HTML 结构:


<input type="button" value="弹窗1">
<input type="button" value="弹窗2">

var aBtn = document.querySelectorAll("input"),
   offset = 20, index = 1;
  function Module( pos ){
   this.offset = pos || 20;
  }
  Module.prototype.create = function(){
   var oDiv = document.createElement( "div" );
   oDiv.style.left = ( ++index ) * offset + 'px';
   oDiv.style.top = ( ++index ) * offset + 'px';
   oDiv.innerHTML = 'ghostwu教你用设计模式实战';
   return oDiv;
  }
  Module.one = (function(){
   var ins = null, isExist = false;
   return function( pos ){
    if ( !ins ) ins = new Module( pos );
    if ( !isExist ) {
     document.body.appendChild( ins.create() );
     isExist = true;
    }
   }
  })();
  aBtn[0].onclick = function(){
   Module.one( 10 );
  }
  aBtn[1].onclick = function(){
   Module.one( 10 );
  }

在 Module.one 方法中,通过变量 isExist 的两种状态结合闭包特性,严格控制 DOM 元素只能被添加至页面一次。

以上即为关于使用 JavaScript 单例模式实现模态框的完整示例,希望能为读者提供有价值的参考,并欢迎大家继续支持本站内容。

作者最新文章