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 Math exp() 方法

    JavaScript中的Math.exp()方法用于返回自然数e的x次幂,其中x是传递给该方法的参数。以下是关于Math.exp()方法的完整攻略,包括两个示例。 JavaScript Math对象的exp()方法 JavaScript Math对象中的exp()方法用于返回自然数e的x次幂,其中x是传递给该方法的参数。 下面是exp()方法的语法: Mat…

    JavaScript 2023年5月11日
    00
  • ASP.NET向Javascript传递变量两种实现方法

    ASP.NET是一个非常常用的Web框架,它提供了可以与Javascript进行交互的方法,本文将详细讲解如何实现ASP.NET向Javascript传递变量的两种常用方法。 方法一:使用hidden field hidden field是一个隐藏的input元素,它可以在服务器端存储数据,作为Javascript代码可以读写的全局变量。下面是ASP.NET…

    JavaScript 2023年6月10日
    00
  • JavaScript中的Reflect对象详解(ES6新特性)

    JavaScript中的Reflect对象详解(ES6新特性) 什么是Reflect对象 Reflect对象是ES6新增的一个内置对象。它提供了一系列操作对象的方法,这些方法的作用与Proxy对象的方法一一对应。 通过Reflect对象,我们可以更加方便和灵活地操作对象,同时提高代码的可读性和可维护性。 Reflect对象提供的方法 Reflect.appl…

    JavaScript 2023年5月27日
    00
  • JavaScript实现简易计算器功能的两种方法

    当需要在网页上实现简单的数学计算时,我们可以使用JavaScript来实现一个简易的计算器,下面介绍两种方法。 方法一:使用eval()函数实现计算器功能 在HTML文件中添加一个文本输入框和一个按钮: <input type="text" id="num"> <button onclick=&quo…

    JavaScript 2023年5月27日
    00
  • JavaScript判断数组的方法总结与推荐

    下面我将为你详细讲解 JavaScript 判断数组的方法总结与推荐的完整攻略。 前言 在 JavaScript 中,判断变量是否为数组的方法有许多,但很多初学者容易混淆。本文将总结常见且实用的判断数组的方法并进行详细的讲解,以帮助读者更好地掌握这些方法。 instanceof 判断 instanceof 是 JavaScript 中的一个二元运算符(即需要…

    JavaScript 2023年5月27日
    00
  • 在JavaScript中使用timer示例

    下面是关于在JavaScript中使用timer的完整攻略: 什么是 Timer? 在 JavaScript 中, Timer 用于将一个代码块延迟一段时间后执行,或者每隔一段时间就重复执行。Timer 有两种类型:setTimeout()和setInterval()。 setTimeout() setTimeout()方法可用于延迟一次性执行代码的执行。可…

    JavaScript 2023年5月27日
    00
  • javaScript产生随机数的用法小结

    下面是JavaScript产生随机数的用法小结: 1. Math.random()方法 在JavaScript中,我们可以使用Math.random()方法产生一个0到1之间的随机数。例如,在以下代码中,我们可以产生一个0到1之间的随机数,并将其乘以10得到一个0到10之间的随机数: let randNum = Math.random() * 10; con…

    JavaScript 2023年5月28日
    00
  • Element Carousel 走马灯的具体实现

    要实现一个Element Carousel 走马灯需要以下几个步骤: 1.引入Element库和样式表 在HTML文件中引入Element库和样式表 <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css&quo…

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