JavaScript编程的单例设计模讲解

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日

相关文章

  • JS使用Date对象实时显示当前系统时间简单示例

    下面我会详细讲解如何使用 JavaScript 的 Date 对象实现实时显示当前系统时间的简单示例。 准备工作 在开始之前,我们需要了解 JavaScript 的 Date 对象,该对象用于处理日期和时间,它提供了获取当前时间、设置时间、获取时间戳等方法。 为了演示该功能,我们需要在页面中添加一个用于显示时间的元素,例如: <div id=&quot…

    JavaScript 2023年5月27日
    00
  • JavaScript 高级语法介绍

    JavaScript 高级语法介绍攻略 什么是 JavaScript 高级语法? JavaScript 高级语法是指相对于语言基础而言更深入、更难掌握的语言知识部分。学习 JavaScript 高级语法可以帮助开发者更加灵活地运用 JavaScript 编程语言,实现更复杂、更高级的功能。 JavaScript 高级语法包括哪些? JavaScript 高级…

    JavaScript 2023年5月18日
    00
  • JSP对URL链接中的中文乱码处理方法总结

    下面我将为您详细讲解“JSP对URL链接中的中文乱码处理方法总结”的完整攻略。 一、问题背景 在JSP中,当我们需要传递中文参数时,URL链接中的中文会出现乱码。这是因为URL中只支持ASCII码,而中文字符不属于ASCII码范围内。因此需要对中文参数进行编码处理,以保证URL链接能够正确传递中文参数。 二、解决方案 1、使用URLEncoder/URLDe…

    JavaScript 2023年5月19日
    00
  • js移动端事件基础及常用事件库详解

    JS移动端事件基础及常用事件库详解 随着移动端的普及,越来越多的网站需要对移动端进行支持。而移动设备和桌面设备不同,触摸屏幕是最主要的交互方式,因此在移动端开发中,事件处理是至关重要的。此文将讲解移动端事件基础概念及常用的事件库。 基础概念 Touch事件 一般来说,移动端只有一种事件——Touch事件。这个事件包含一系列的属性,其中最重要的是以下三个: e…

    JavaScript 2023年6月11日
    00
  • JS/jQuery判断DOM节点是否存在的简单方法

    当我们使用 JavaScript 或者 jQuery 操作 DOM 节点时,有时候需要判断一个元素是否存在于页面中。以下是几种简单的方法来判断 DOM 节点是否存在。 方法一:使用 jQuery 长度属性 我们可以使用 jQuery 长度属性 .length() 来判断元素是否存在。如果元素不存在,它的长度为 0,反之则大于 0。 // 判断元素存在 if …

    JavaScript 2023年6月10日
    00
  • 详解Js 根据文件夹目录获取Json数据输出demo

    下面是详解 “JS 根据文件夹目录获取 Json 数据输出 demo” 的完整攻略。 1. 概述 本攻略主要讲解如何使用 JS 根据文件夹目录获取 json 数据,最终输出到页面中。具体实现方式是对文件夹目录进行遍历,生成对应的 json 数据,然后输出到页面中。 2. 准备工作 在开始之前,需要准备一些开发环境和依赖: Node.js,用于在后台生成 js…

    JavaScript 2023年5月27日
    00
  • 用js自动判断浏览器分辨率的代码

    确定浏览器分辨率的方法有很多种,其中一种方法就是使用JavaScript代码来获取浏览器分辨率。以下是实现该功能的方法: 方法一:使用screen对象 我们可以使用 screen 对象来获取用户的屏幕分辨率。 let screenWidth = screen.width; let screenHeight = screen.height; console.l…

    JavaScript 2023年6月11日
    00
  • 微信小程序开发入门基础教程

    微信小程序开发入门基础教程 前言 微信小程序是一种全新的应用形态,可以在微信中打开,使用前端技术进行开发。相比传统APP而言,微信小程序不需要安装,用户可以直接通过微信扫描二维码或者搜索来使用。本文将从基础入门开始,介绍微信小程序的开发过程。 准备工作 在开始微信小程序开发之前,需要准备好以下环境:1. 微信开发者工具,可以在这里下载。2. 微信公众平台账号…

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