本文深入解析JavaScript中的单例模式,通过构建全局唯一的登录弹窗实例,演示如何确保类仅有一个实例并提供全局访问点。内容涵盖DOM获取、构造函数定义、原型方法(如create和delete)的实现,以及利用闭包和||运算符创建唯一实例的核心技巧,帮助开发者提升代码的可维护性与逻辑清晰度。
前言与单例模式概述
前言
与其他编程语言类似,JavaScript也包含多种设计模式,例如单例模式、代理模式和观察者模式等。熟练掌握这些设计模式有助于使代码逻辑更加清晰,从而提升代码的可维护性和重构便利性。
本文将重点介绍JavaScript中的单例模式。在传统软件开发视角下,单例模式的核心在于确保一个类仅有一个实例,其实现方式通常是先检查实例是否存在:若存在则直接返回,若不存在则创建后返回,以此保证全局唯一性。在JavaScript中,单例模式常作为命名空间提供者,从全局命名空间中提供一个唯一的访问入口来操作该对象。下文将展开详细介绍。
单例模式概念解析
单例模式概念
首先明确什么是单例模式?其核心定义是:确保一个类仅有一个实例,并提供一个全局的访问点。
若对上述概念仍感抽象,可参考生活中的实例。例如注册账号时,若系统检测到该账号已存在,会提示“账号已存在,是否登录”,此时用户无法再次创建完全相同的账号,除非注销原账号。这便是单例模式的生动体现。
另一个常见例子是网页上的登录弹窗。无论用户点击多少次登录按钮,界面上始终只显示一个登录弹窗,无法创建第二个相同的弹窗实例。
本文将基于上述登录弹窗的场景,详细演示单例模式的具体使用方式。
单例模式实例:登录弹窗实现
单例模式实例
1.demo展示

2.代码展示
虽然构建单例模式弹窗的代码实现因人而异,但其核心目标一致:构建一个全局唯一且可访问的弹窗实例。接下来我们将分步骤实现该示例。
(1)获取DOM对象
var $ = function(id) {
return typeof id === 'string' ? document.getElementById(id) : id;
};
为了便于后续对DOM进行操作,我们利用函数式编程原理封装了一个获取指定id元素的方法,直接调用$(id)即可获取目标DOM对象。
(2)弹框构造函数
var Modal = function(id, html) {
this.html = html;
this.id = id;
this.open = false;
};
此处声明了一个名为Modal的构造函数,并在其内部定义了公有属性html、id和open。其中,html用于定义弹窗内部的内容,id用于指定弹窗的标识符,open属性用于标记弹窗当前是否处于打开状态。
(3)open方法
Modal.prototype.create = function() {
if (!this.open) {
var modal = document.createElement('div');
modal.innerHTML = this.html;
modal.id = this.id;
document.body.appendChild(modal);
setTimeout(function() {
modal.classList.add('show');
}, 0);
this.open = true;
}
};
我们在Modal的原型链上定义了create方法。该方法内部负责创建弹窗并将其插入DOM,同时为弹窗添加class为“show”的动画效果。此处简要介绍classList:
classList是一个比className更便捷的操作元素class属性的API,不过其兼容性不支持IE10以下版本:
classList兼容性
它提供的class操作方法与jQuery类似,主要包括:
add(class1, class2, ...) 用于在元素中添加一个或多个类名,功能类似jQuery的addClass()
remove(class1, class2, ...) 用于移除元素中的一个或多个类名,功能类似jQuery的removeClass()
contains(class) 用于判断指定的类名是否存在,功能类似jQuery的hasClass()
在本例中,我们使用了add方法为Modal添加show类。
(4)close方法
Modal.prototype.delete = function() {
if (this.open) {
var modal = $(this.id);
modal.classList.add('hide');
setTimeout(function() {
document.body.removeChild(modal);
}, 200);
this.open = false;
}
};
定义了open方法后,我们进一步定义关闭弹窗的方法。该方法内部为弹窗对象添加hide类的动画效果,并在页面加载完成后移除弹窗对象。
(5)创建实例
var createIntance = (function() {
var instance;
return function() {
return instance || (instance = new Modal('modal', '这是一个弹框'))
}
})();
这是实现单例模式的关键部分,我们分析其中的知识点:
1、使用闭包封装了instance私有变量,并返回一个函数
2、利用 || 语法判断:如果instance不存在,则执行后者的实例化Modal方法;如果存在,则直接返回instance,从而确保系统中只存在一个弹窗实例。
本实例的创建过程也可视为代理模式的一部分。
(6)按钮操作
var operate = {
setModal: null,
open: function() {
this.setModal = createIntance();
this.setModal.create();
},
delete: function() {
this.setModal ? this.setModal.delete() : '';
}
};
我们将按钮的操作逻辑封装在operate对象中,使得打开和关闭操作可以通过this获取实例setModal。
(7)绑定事件
$('open').onclick = function() {
operate.open();
};
$('delete').onclick = function() {
operate.delete();
};
最后,我们将打开和删除方法分别绑定到两个按钮上。至此,基于单例模式实现的弹窗Demo即告完成。
总结
总结
本文仅演示了单例模式的一种实现方式,如何构建通用的单例模式留给感兴趣的读者探索。以上就是本文的全部内容,希望能对您的学习或工作有所帮助。