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日

相关文章

  • 一文让你快速了解JavaScript栈

    随着前端技术的不断发展,JavaScript已经成为一种非常重要的编程语言。为了让大家更好地理解JavaScript的运行机制,我准备了一篇文章,希望能够帮助大家快速了解JavaScript栈。 什么是JavaScript栈 JavaScript栈是指一种数据结构,它被用来存储函数调用时的上下文信息。每一次函数调用,JavaScript都会把该函数的上下文信…

    JavaScript 2023年5月18日
    00
  • js实现图片轮换效果代码

    下面是JS实现图片轮换效果的完整攻略。 确定轮换效果的基本样式 在实现图片轮换效果之前,我们需要先确定图片轮换效果的基本样式。通常的图片轮换效果包括以下几个特征: 轮换的图片需要以一定的间隔时间进行切换 图片的切换需要具有一定的动效 切换的图片需要在轮换效果的容器中进行展示 因此,我们可以先定义一个基本的样式,包含一个轮换容器和轮换的图片,其中轮换的图片通过…

    JavaScript 2023年6月11日
    00
  • Javascript四舍五入Math.round()与Math.pow()使用介绍

    Javascript四舍五入Math.round()与Math.pow()使用介绍 Math.round() 在Javascript中,可以使用Math.round()方法将小数进行四舍五入。 其语法如下: Math.round(x) 其中,x为需要四舍五入的数字。 例如,对于数字1.2使用Math.round()方法进行四舍五入: var rounded …

    JavaScript 2023年6月10日
    00
  • 正则表达式中test、exec、match的区别介绍及括号的用法

    正则表达式是用于匹配文本的强大工具,它允许您使用模式来搜索、替换和操作文本。在使用正则表达式时,test、exec、match及括号都是常用的概念,它们的用法与意义都不同。 test、exec、match的区别介绍 test方法 test方法是RegExp对象的方法之一,它的作用是测试一个字符串是否匹配某个正则表达式,返回布尔值。如果匹配成功,test方法返…

    JavaScript 2023年6月10日
    00
  • js关闭浏览器窗口及检查浏览器关闭事件

    要实现JavaScript关闭浏览器窗口以及检查浏览器关闭事件,可以使用window.close()方法和window.onbeforeunload事件。 使用window.close()方法关闭浏览器窗口 使用window.close()方法可以轻易地关闭当前窗口或打开的窗口。但要注意,在现代浏览器中,该方法只能关闭由JavaScript打开的窗口,不能关…

    JavaScript 2023年6月11日
    00
  • ES6中字符串string常用的新增方法小结

    ES6中字符串string常用的新增方法有很多,本文将对其中常用的方法进行小结,帮助读者更好地理解和使用ES6字符串方法。 1. 字符串模板(Template) 字符串模板(Template)在ES6中是一项非常重要的新功能,它使我们可以更加方便地处理字符串拼接。 1.1 语法 模板字符串使用反引号(“`)包裹字符串,可以在字符串中插入变量或表达式: le…

    JavaScript 2023年5月28日
    00
  • Javascript常用字符串判断函数代码分享

    下面是详细的Javascript常用字符串判断函数代码分享。 前言 在Javascript编程中,字符串判断是一个非常重要的部分。字符串判断函数主要是用于判断字符串是否符合某些功能的要求。因此,开发者在编写代码时,需要适时的调用这些函数。接下来,我们将分享一些常用的字符串判断函数。 字符串判断函数 1. includes() includes() 函数可以用…

    JavaScript 2023年5月19日
    00
  • jQuery 遍历json数组的实现代码

    当使用jQuery操作JSON数据时,我们需要使用 $.each() 或 $.map() 函数来遍历JSON对象或数组。以下是完整的攻略: 1.读取JSON数据 在使用jQuery遍历JSON数据前,我们需要先读取JSON数据。我们可以使用 $.getJSON() 函数从服务器读取JSON数据。 $.getJSON(‘/data.json’, functio…

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