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 数组的 uniq 方法

    下面是更新 JavaScript 数组的 uniq 方法的完整攻略: 1. 现状 目前,虽然 JavaScript 数组已有现成的 filter 函数可以用来过滤数组中重复的元素,但很多开发者经常需要自定义数组的 uniq 方法,以实现更加灵活的去重操作。目前,常见的去重实现方式有两种:基于 Set 对象的去重和基于对象属性的去重,其中基于 Set 的去重是…

    JavaScript 2023年5月27日
    00
  • JQuery插入DOM节点的方法

    JQuery是一款操作DOM的JavaScript库,提供了很多操作DOM节点的方法,包括插入DOM节点的方法。以下是关于JQuery插入DOM节点的方法的完整攻略: 一、插入DOM节点的方法 在JQuery中,插入DOM节点的方法可以使用以下几种: 1.append()方法 append() 方法向被选元素的结尾(即作为其最后一个子元素)插入指定内容。 /…

    JavaScript 2023年6月10日
    00
  • 详解vue route介绍、基本使用、嵌套路由

    让我们来详细讲解一下Vue Route的相关信息。 1. 什么是Vue Route Vue Route是Vue.js官方提供的用于实现客户端路由的插件。它实现了基于组件的路由,使得我们可以通过改变URL的方式来呈现不同的页面内容,从而实现单页应用(SPA)的路由系统。 2. 基本使用 为了使用Vue Route,我们需要在Vue项目中先安装它。我们可以通过在…

    JavaScript 2023年6月11日
    00
  • js实现汉字排序的方法

    下面是js实现汉字排序的方法的详细攻略。 准备工作 在实现汉字排序之前需要准备一些工作。 安装JavaScript工具库pinyin。 npm install pinyin –save 引入pinyin工具库。 const pinyin = require(‘pinyin’); 实现步骤 获取待排序汉字数组。 const hanziArr = [‘北京’,…

    JavaScript 2023年5月19日
    00
  • 新浪微博COOKIES盗取[flash编程安全+apache http-only cookie 泄漏利用]

    首先,需要了解COOKIES的作用,简单来说,COOKIES是一个保存在浏览器上的文本文件,它可以记录用户访问过的页面和提供给网站的个人信息等,以方便下次用户访问时快速获得所需的内容。然而,COOKIES也有它的弊端,比如可能被黑客盗取,从而获取用户的个人信息。 在此,我们就讲解一下新浪微博COOKIES盗取的攻略步骤: 确定攻击目标 首先,需要确定攻击的目…

    JavaScript 2023年6月11日
    00
  • javascript replace()正则替换实现代码

    关于JavaScript中的replace()方法,它可以接受两个参数,第一个参数为一个正则表达式或者字符串类型的文本,表示待匹配的内容;第二个参数可以是一个替换字符串或者一个函数,表示将匹配到的内容替换成对应的字符串或函数返回的值。 下面是实现JavaScript正则替换的详细攻略: 1. 使用字符串实现替换 当第一个参数是一个字符串类型的文本时,可以直接…

    JavaScript 2023年5月28日
    00
  • vue实现路由跳转动态title标题信息

    下面是vue实现路由跳转动态title标题信息的完整攻略: 使用vue-router管理路由 在vue中,我们可以使用vue-router管理路由,对应的npm包名为vue-router。使用vue-router能够方便的实现从页面跳转到另外一个页面,同时在页面跳转时可以动态修改页面的标题信息。具体步骤如下: 安装vue-router 在项目中使用vue-r…

    JavaScript 2023年6月11日
    00
  • javaScript遍历对象和数组的方法总结

    JavaScript遍历对象和数组的方法总结 在JavaScript中,遍历对象和数组是非常重要的操作。对象和数组中都有各种各样的数据,我们需要用不同的方式去遍历它们并对其进行处理。本文将详细介绍JavaScript中遍历对象和数组的方法。 遍历对象的方法 在JavaScript中,一般使用for…in循环来遍历对象。for…in循环会遍历对象的所有…

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