JavaScript编程的单例设计模讲解

yizhihongxing

JavaScript编程的单例设计模式讲解

在JavaScript开发中,单例模式是一个常见的设计模式。它可以保证一个类只有一个实例,并提供一个全局可访问该实例的访问点。

使用场景

当一个对象需要在整个应用程序中只有一个实例时,就可以考虑使用单例模式。如:

  1. 全局状态管理
  2. 路由管理
  3. 模态框管理
  4. 数据库连接池
  5. WebSocket连接管理等。

基本实现方式

let singleton = (function(){
  let instance;

  function init() {    
    // 私有方法和私有属性
    let privateVar = 'I am private';
    function privateMethod() {
      console.log('This is private method');
    }

    // 公有方法和属性
    return {
      publicMethod: function() {
        console.log('This is public method');
      },
      publicVar: 'I am public',

      // 获取实例
      getInstance: function() {
        if (!instance) {
          instance = init();
        }
        return instance;
      }
    }
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  }
})();

let s1 = singleton.getInstance();
let s2 = singleton.getInstance();
console.log(s1 === s2); // true

以上代码使用了闭包和IIFE的特性,使得init函数只会执行一次并返回全局唯一的单例对象。

示例说明

示例1:全局状态管理

假设我们需要实现一个全局唯一的状态管理器,并且需要实现以下功能:

  1. getState方法获取当前状态
  2. setState方法设置当前状态
  3. subscribe方法订阅状态变更事件
  4. notify方法通知所有订阅者状态变更事件

基于上述需求,我们可以使用单例模式实现一个状态管理器:

let stateManager = (function(){
  let instance;

  function init() {    
    let state = 0;
    let subscribers = [];

    function notifySubscribers() {
      for(let i=0; i<subscribers.length; i++) {
        subscribers[i]();
      }
    }

    return {
      getState: function() {
        return state;
      },
      setState: function(s) {
        state = s;
        notifySubscribers();
      },
      subscribe: function(fn) {
        subscribers.push(fn);
      },

      getInstance: function() {
        if (!instance) {
          instance = init();
        }
        return instance;
      }
    }
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  }
})();

// 调用
let sm1 = stateManager.getInstance();
let sm2 = stateManager.getInstance();
console.log(sm1 === sm2); // true

sm1.subscribe(() => console.log('状态变更了:' + sm1.getState()));
sm1.setState(1);
sm1.setState(2);

示例2:WebSocket连接管理

假设我们需要实现一个全局唯一的WebSocket连接管理器,并且需要实现以下功能:

  1. open方法打开一个WebSocket连接,并自动重连
  2. send方法向指定连接发送消息
  3. close方法关闭指定连接
  4. getAll方法获取所有连接状态

基于上述需求,我们可以使用单例模式实现一个WebSocket连接管理器:

let wsManager = (function(){
  let instance;

  function init() {
    let connections = [];

    function open(url) {
      let conn = new WebSocket(url);
      connections.push(conn);

      conn.addEventListener('open', () => {
        console.log('连接已建立:' + url);
      });

      conn.addEventListener('message', (e) => {
        console.log('收到消息:' + e.data);
      });

      conn.addEventListener('close', () => {
        console.log('连接已关闭:' + url);
        setTimeout(() => open(url), 1000);
      });

      return conn;
    }

    function close(conn) {
      conn.close();
      connections.splice(connections.indexOf(conn), 1);
      console.log('连接已关闭:' + conn.url);
    }

    function send(conn, message) {
      conn.send(message);
      console.log('向' + conn.url + '发送字符串消息:' + message);
    }

    function getAll() {
      let result = [];
      for (let i=0; i<connections.length; i++) {
        result.push({ url: connections[i].url, readyState: connections[i].readyState });
      }
      return result;
    }

    return {
      open: function(url) {
        return open(url);
      },
      close: function(conn) {
        return close(conn);
      },
      send: function(conn, message) {
        return send(conn, message);
      },
      getAll: function() {
        return getAll();
      },

      getInstance: function() {
        if (!instance) {
          instance = init();
        }
        return instance;
      }
    }
  }

  return {
    getInstance: function() {
      if (!instance) {
        instance = init();
      }
      return instance;
    }
  }
})();

// 调用
let ws = wsManager.getInstance().open('ws://localhost:8080/');
wsManager.getInstance().send(ws, 'hello');
wsManager.getInstance().close(ws);
console.log(wsManager.getInstance().getAll());

上述两个示例分别实现了全局状态管理和WebSocket连接管理的功能,并都应用了单例模式来保证全局唯一性。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript编程的单例设计模讲解 - Python技术站

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

相关文章

  • JavaScript 常用函数

    现在我将为您详细讲解 JavaScript 常用函数的完整攻略。 一、JavaScript 常用函数介绍 JavaScript 提供了很多函数,可以让我们更加方便的处理数据和操作 DOM。在这里,我们将介绍一些常用的 JavaScript 函数,它们在日常工作中非常常用。 1. parseInt() parseInt() 函数可以将一个字符串解析成整数。它的…

    JavaScript 2023年5月18日
    00
  • p5.js实现简单货车运动动画

    实现简单货车运动动画可以使用p5.js中的画布和动画函数,下面是一个完整的攻略。 1. 准备工作 在开始编写代码之前,我们需要做一些准备工作。 Step 1: 引入p5.js库 我们需要在HTML文档中引入p5.js库,可以通过以下方式来实现: <!DOCTYPE html> <html lang="en"> &l…

    JavaScript 2023年6月10日
    00
  • JavaScript进阶教程(第二课续)第2/2页

    JavaScript进阶教程(第二课续)第2/2页攻略 一、概述 本教程将对JavaScript进阶知识进行详细讲解,其中包括以下三个部分: 进阶语法特性介绍 函数式编程介绍与应用 异步编程与Promise 二、进阶语法特性介绍 1. Rest参数 Rest参数允许在定义函数时使用不限数量的参数,这些参数将被自动转换为数组,方便对参数进行遍历: functi…

    JavaScript 2023年5月18日
    00
  • JS对象数组中如何匹配某个属性值

    针对这个问题,我们可以分为以下几个步骤进行说明: 定义一个JS对象数组; 遍历数组,检查所有对象是否包含指定的属性值; 如果找到指定的对象,就返回该对象;如果没有找到,就返回 undefined。 下面是具体的代码实现和示例: 定义 JS 对象数组 首先我们需要定义一个包含一组 JS 对象的数组,如下所示: let students = [ { id: 1,…

    JavaScript 2023年6月10日
    00
  • JavaScript reduce方法使用方法介绍

    当我们需要对数组进行一系列的计算操作时,reduce()方法就非常有用了。本篇攻略将带您详细了解JavaScript中的reduce()方法,包括使用方法、参数、返回值。 reduce()方法介绍 reduce()方法是JavaScript数组的高阶函数之一,其作用在于通过遍历数组中的所有元素并将它们累加起来,最终返回一个结果。 array.reduce(c…

    JavaScript 2023年6月10日
    00
  • C#应用ToolStrip控件使用方法

    C#应用ToolStrip控件使用方法 在C#中,ToolStrip控件可以用于创建菜单栏、工具栏、状态栏等用户界面元素。本文将介绍在C#应用中如何使用ToolStrip控件。 步骤一:添加ToolStrip控件到窗体 要使用ToolStrip控件,首先需要将其添加到窗体中。可以通过拖拽控件添加的方式,或者在窗体的Load事件中手动创建并添加控件,这里我们以…

    JavaScript 2023年5月28日
    00
  • js实现图片轮播效果学习笔记

    下面是“js实现图片轮播效果学习笔记”的详细攻略。 什么是图片轮播效果? 图片轮播效果是一种常见的前端交互效果,它通常被用于网站首页的展示或者是产品推广的页面。通常,图片轮播效果由若干张图片组成,图片会在页面上自动进行轮播,并提供一些控制按钮供用户手动切换图片。 实现图片轮播效果的基本步骤 实现图片轮播效果的基本步骤大致如下: 编写HTML和CSS代码,实现…

    JavaScript 2023年6月11日
    00
  • Javascript倒计时代码

    JavaScript 倒计时能够给网站或者应用程序带来极佳的用户体验,它通常用于页面的时间限制、登录等场景。下面是 JavaScript 倒计时的完整攻略。 步骤1:创建 HTML 页面 首先,我们需要在 HTML 页面中添加一个画布元素 canvas 以及 JavaScript 倒计时所需要的 HTML 元素: <!DOCTYPE html> …

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