JavaScript设计模式—单例模式详解【四种基本形式】

JavaScript设计模式---单例模式详解【四种基本形式】

单例模式是一种常用的设计模式,它是指在整个应用程序中只需要实例化一次的类。在JavaScript中,单例模式具有着特殊的意义。因为JavaScript是一种无状态语言,每次请求网页都会加载一次JavaScript文件,如果我们没使用单例模式来管理,可能会在内存中生成多个对象实例,造成资源的浪费,而且数据容易混乱。

普通形式

普通的单例模式大概长这样:

var Singleton = function(name) {
  this.name = name;
  this.instance = null; // 标示属性
};

Singleton.prototype.getName = function() {
  console.log(this.name);
};

Singleton.getInstance = function(name) {  // 静态方法
  if (!this.instance) {  // 如果已经存在实例直接返回
    this.instance = new Singleton(name);
  }
  return this.instance;
}

// 利用静态方法创建实例
var s1 = Singleton.getInstance('张三');
var s2 = Singleton.getInstance('李四');
s1.getName();  // 张三
s2.getName();  // 张三
console.log(s1 === s2); // true

以上代码中,我们创建了一个Singleton单例类,并为其添加了getName方法和静态方法getInstance

静态方法是指定义在类上的方法(该方法并不能在实例上调用,你可以粗略的把它理解为类级别的方法)。它可以方便我们直接调用这个方法,而不需要先实例化一个对应的对象,例如在以上示例中我们可以这样调用Singleton.getInstance('张三'),当我们需要使用这个类时,我们直接使用Singleton.getInstance方法即可。如果这个类的实例不存在,那么就创建一个实例,并把它存储在instance中;下次请求实例时,直接返回已经创建的实例对象,该示例中是通过一个标示属性instance来标记这个类是否被实例化(如果已经有实例,就不会再次创建)。

在以上示例中,我们创建了两个不同的实例s1s2,但是它们的name属性值都是“张三”。通过console.log(s1 === s2)我们可以看到它们的值为true,说明s1s2都是指向同一个对象的引用,也就是说这一整个过程中只创建了一个实例。

Javascript的缓存机制形式

除了普通形式,我们还可以将缓存机制来实现单例模式。由于函数也是对象,所以我们可以用闭包来封装私有变量。

var Singleton = function(fn) {
  var instance;
  return function() {
    return instance || (instance = fn.apply(this, arguments));
  }
}

var createLoginLayer = function() {
  var div = document.createElement('div');
  div.innerHTML = '我是登录浮窗';
  div.style.display = 'none';
  document.body.appendChild(div);
  return div;
};

var getSingleLoginLayer = Singleton(createLoginLayer); // 单例模式
document.getElementById('loginBtn').onclick = function() {
  var loginLayer = getSingleLoginLayer();
  loginLayer.style.display = 'block';
}

以上示例中,我们创建了一个闭包函数Singleton,这个函数将一个函数作为参数fn传入,然后返回一个内置函数。这个内置函数首先声明了 instance 变量,然后在每次函数被调用时,检查 instance 变量是否有值。如果有值,就返回这个 instance 变量,而不是重新创建一个对象。如果没有,就调用传入 Singleton 函数的这个函数(例如我们在这个示例中传入的 createLoginLayer)来创建一个对象,并将这个对象赋值给 instance 变量,最后返回这个对象。由于浏览器缓存机制的存在,下次我们点击登录按钮时,不需要再次重复创建这个登录浮窗,而是直接获取前一个浮窗就行了。

惰性单例模式

惰性单例是指在需要的时候才去创建对象实例。

var createLoginLayer = function() {
  var div = document.createElement('div');
  div.innerHTML = '我是登录浮窗';
  div.style.display = 'none';
  document.body.appendChild(div);
  return div;
};

var createSingleLoginLayer = (function() {
  var instance;
  return function() {
    return instance || (instance = createLoginLayer());
  }
})();

document.getElementById('loginBtn').onclick = function() {
  var loginLayer = createSingleLoginLayer();
  loginLayer.style.display = 'block';
}

以上示例中,我们使用立即执行函数(IIFE)对单例对象进行了包装,并且在返回的函数中对单例对象进行判断,如果单例对象已经存在,则直接返回。如果不存在,则先进行初始化操作。这样就实现了只有在有需要时才对单例的对象进行初始化。

通过以上三种实现方式,我们可以发现单例模式的核心思想:控制实例的数量,节约系统资源。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript设计模式—单例模式详解【四种基本形式】 - Python技术站

(0)
上一篇 2023年6月10日
下一篇 2023年6月10日

相关文章

  • JavaScript时间戳与时间日期间相互转换

    下面我将详细讲解“JavaScript 时间戳与时间日期间相互转换”的完整攻略。 什么是时间戳? 时间戳是用于表示时间的一种方式,它是自1970年1月1日 00:00:00 UTC到当前时间的毫秒数。JavaScript只支持精确到毫秒级别的时间戳。 时间戳的好处是可以通过它来进行时间比较或计算时间差等操作,并且可以通过时间戳在不同的设备和系统之间进行时间的…

    JavaScript 2023年5月27日
    00
  • js屏蔽退格键(backspace或者叫后退键与F5)

    下面是 JS 屏蔽退格键(backspace)和F5键的完整攻略,包含了两个示例说明: 如何屏蔽退格键和F5键 当用户在执行操作的时候,有时候不希望用户误操作将页面刷新或者回退,所以需要屏蔽一些按键,比如退格键和F5键。下面就来讲解具体的屏蔽方式。 屏蔽退格键(backspace) document.onkeydown = function() { if (…

    JavaScript 2023年6月11日
    00
  • 详解Jotai Immer如何实现undo redo功能示例详解

    详解Jotai Immer如何实现undo redo功能示例详解 Jotai Immer是一个结合了Jotai和Immer两种状态管理库的工具,其中Immer提供了基于不可变数据结构的状态修改方式,Jotai则提供了状态的管理和更新功能。通过结合使用两个库,我们可以更加方便地进行状态管理,并实现undo redo功能。 安装和引入 首先,我们需要安装Jota…

    JavaScript 2023年6月11日
    00
  • JS基于Location实现访问Url、重定向及刷新页面的方法分析

    让我详细讲解一下 “JS基于Location实现访问Url、重定向及刷新页面的方法分析” 的完整攻略。 什么是 Location 对象? Location 对象代表了当前窗口中当前文档的URL,还提供了与URL相关的信息和一些导航功能。它是window对象下的属性,所以可以通过 window.location 或者 location 来访问。 访问URL 获…

    JavaScript 2023年5月28日
    00
  • 28个JavaScript常用字符串方法以及使用技巧总结

    28个JavaScript常用字符串方法以及使用技巧总结 1. 字符串长度 通过 length 属性可以获取字符串的长度。 const str = ‘Hello World’; console.log(str.length); // 11 2. 字符串截取 常见的字符串截取方式为 substring 和 slice,两者用法类似,都是根据起始位置和结束位置截…

    JavaScript 2023年5月18日
    00
  • JavaScript中使用stopPropagation函数停止事件传播例子

    下面是详细讲解“JavaScript中使用stopPropagation函数停止事件传播”的攻略。 一、什么是事件传播 在 JavaScript 中,事件传播是指一个正在执行的事件被传递到多个目标元素时的行为。当事件发生时,它将从最深嵌套的 DOM 元素(称为目标)开始,然后传递到 DOM 树的根,逐步往上传递,直到文档的顶部。事件可以在传播的过程中被捕获和…

    JavaScript 2023年5月28日
    00
  • 学习JavaScript设计模式(策略模式)

    学习JavaScript设计模式之策略模式 什么是策略模式?策略模式是一种行为设计模式,它能让你定义一系列算法,将它们封装到一个个独立的类中,可以使它们相互替换。策略模式使得算法可以独立于使用它们的客户端而变化。 在JavaScript中,策略模式通常是通过定义不同的函数来实现的。根据需要,你可以将算法添加到一个对象中,然后把这个对象传递给执行某个方法的函数…

    JavaScript 2023年5月18日
    00
  • JavaScript字符串操作的四个实用技巧

    当涉及到JavaScript字符串操作时,有许多材料可供学习者研读。但是,当你想要张贴或处理字符串时,这里提供了四个实用技巧,使得你的编程更加高效简洁。 技巧1:字符串长度和切片 注意到JavaScript字符串本质上是字符数组,你可以使用JavaScript 来计算字符串的长度以及对它进行切片,如下所示: const stringVariable = ‘H…

    JavaScript 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部