首页 > 编程语言 >【JS】164-JavaScript设计模式——单体模式

【JS】164-JavaScript设计模式——单体模式

时间:2022-11-28 14:01:16浏览次数:40  
标签:obj name JavaScript JS a1 let new 设计模式 Leo

【JS】164-JavaScript设计模式——单体模式_构造函数

一、单体模式(Singleton Pattern)

1.概念介绍

单体模式(Singleton Pattern)的思想在于保证一个特定类仅有一个实例,即不管使用这个类创建多少个新对象,都会得到与第一次创建的对象完全相同

它让我们能将代码组织成一个逻辑单元,并可以通过单一变量进行访问。

单体模式有以下优点:

  • 用来划分命名空间,减少全局变量数量。
  • 使代码组织的更一致,提高代码阅读性和维护性。
  • 只能被实例化一次。

但在JavaScript中没有类,只有对象。当我们创建一个新对象,它都是个新的单体,因为JavaScript中永远不会有完全相等的对象,除非它们是同一个对象。
因此,我们每次使用对象字面量创建对象的时候,实际上就是在创建一个单例

  1. ​let a1 = { name : 'leo' };​
  2. ​let a2 = { name : 'leo' };​
  3. ​a1 === a2; // false​
  4. ​a1 == a2; // false​

这里需要注意,单体模式有个条件,是该对象能被实例化,比如下面这样就不是单体模式,因为它不能被实例化:

  1. ​let a1 = {​
  2. ​ b1: 1, b2: 2,​
  3. ​ m1: function(){​
  4. ​ return this.b1;​
  5. ​ },​
  6. ​ m2: function(){​
  7. ​ return this.b2;​
  8. ​ }​
  9. ​}​
  10. ​new a1(); // Uncaught TypeError: a1 is not a constructor​

下面展示一个单体模式的基本结构:

  1. ​let Singleton = function (name){​
  2. ​ this.name = name;​
  3. ​ this.obj = null;​
  4. ​}​
  5. ​Singleton.prototype.getName = function(){​
  6. ​ return this.name;​
  7. ​}​
  8. ​function getObj(name){​
  9. ​ return this.obj || (this.obj = new Singleton(name));​
  10. ​}​
  11. ​let g1 = getObj('leo');​
  12. ​let g2 = getObj('pingan');​
  13. ​g1 === g2; // true​
  14. ​g1 == g2; // true​
  15. ​g1.getName(); // 'leo'​
  16. ​g2.getName(); // 'leo'​

从这里可以看出,单体模式只能实例化一次,后面再调用的话,都是使用第一次实例化的结果。

2.应用场景

单例模式只允许实例化一次,能提高对象访问速度并且节约内存,通常被用于下面场景:

  • 需要频繁创建再销毁的对象,或频繁使用的对象:如:弹窗,文件;
  • 常用的工具类对象;
  • 常用的资源消耗大的对象;

3.实现弹框案例

这里我们要用单体模式,创建一个弹框,大概需要实现:元素值创建一次,使用的时候直接调用。
因此我们这么做:

  1. ​let create = (() => {​
  2. ​ let div;​
  3. ​ return () => {​
  4. ​ if(!div){​
  5. ​ div = document.createElement('div');​
  6. ​ div.innderHTML = '我是leo创建的弹框';​
  7. ​ div.style.display = 'none';​
  8. ​ div.setAttribute("id", "leo");​
  9. ​ document.body.appendChild(div);​
  10. ​ }​
  11. ​ return div;​
  12. ​ }​
  13. ​})();​
  14. ​// 触发事件​
  15. ​document.getElementById('otherBtn').onclick = () => {​
  16. ​ let first = create();​
  17. ​ first.style.display = 'block';​
  18. ​}​

4.使用new操作符

由于JavaScript中没有类,但JavaScript有 ​​new​​​语法来用构造函数创建对象,并可以使用这种方法实现单体模式。
当使用同一个构造函数以 ​​​new​​操作符创建多个对象,获得的是指向完全相同的对象的新指针。

通常我们使用 ​​new​​操作符创建单体模式的三种选择,让构造函数总返回最初的对象:

  • 使用全局对象来存储该实例(不推荐,容易全局污染)。
  • 使用静态属性存储该实例,无法保证该静态属性的私有性。
  1. ​function Leo(name){​
  2. ​ if(typeof Leo.obj === 'object'){​
  3. ​ return Leo.obj;​
  4. ​ }​
  5. ​ this.name = name;​
  6. ​ Leo.obj = this;​
  7. ​ return this;​
  8. ​}​
  9. ​let a1 = new Leo('leo');​
  10. ​let a2 = new Leo('pingan');​
  11. ​a1 === a2 ; // true​
  12. ​a1 == a2 ; // true​

唯一的缺点就是 ​​obj​​属性是公开的,容易被修改。

  • 使用闭包将该实例包裹,保证实例是私有性并不会被外界修改。

我们这通过重写上面的方法,加入闭包:

  1. ​function Leo(name){​
  2. ​ let obj;​
  3. ​ this.name = name;​
  4. ​ obj = this; // 1.存储第一次创建的对象​
  5. ​ Leo = function(){ // 2.修改原来的构造函数​
  6. ​ return obj;​
  7. ​ }​
  8. ​}​
  9. ​let a1 = new Leo('leo');​
  10. ​let a2 = new Leo('pingan');​
  11. ​a1 === a2 ; // true​
  12. ​a1 == a2 ; // true​

当我们第一次调用构造函数,像往常一样返回this,而后面再调用的话,都将重写构造函数,并访问私有变量 ​​obj​​并返回。

参考资料

  1. 《JavaScript Patterns》

【JS】164-JavaScript设计模式——单体模式_实例化_02


标签:obj,name,JavaScript,JS,a1,let,new,设计模式,Leo
From: https://blog.51cto.com/u_11887782/5891099

相关文章

  • 【正则】223-JS常用正则表达式备忘录
    ​翻译自RegexCheatSheet(https://dev.to/emmawedekind/regex-cheat-sheet-2j2a)翻译:前端小智整理编辑:SegmentFault正则表达式或“regex”用于匹配字符串的各个部分,下面是作......
  • JavaWeb项目实战一(Servlet+Jsp项目项目搭建及登录界面)
    之前JavaWeb学的不是太好,准备从下边列的三个发展阶段,每个阶段以项目形式去补充基础JavaWeb发展阶段:Servlet+JspSSM:SpringMVC+Spring+MyBatis其实在中间阶段还存在......
  • EF Core | Passing navigation properties in JSON body to API controller as POST r
    EFCore|PassingnavigationpropertiesinJSONbodytoAPIcontrollerasPOSTrequestHere'stheofficialdocsonavoidinggraphcyclesinJSON:learn.micros......
  • day33- js基础语法
    字符串正常字符串使用单双引号包裹转义字符\'\n\t\u4e2d(\u####)unicode字符Ascll字符多行字符串``tab键上面的``包含多行字符模板字符串需要使......
  • JS中的变量提升与函数提升
    一段JS代码在执行的时候,大致可以分为两步。第一步为对代码的编译阶段,第二步才是真正去执行各语句。代码中用关键字var的变量声明和函数声明(非函数表达式)会在编译阶段提升到......
  • 12个有用的JavaScript数组技巧
    数组是Javascript最常见的概念之一,它为我们提供了处理数据的许多可能性,熟悉数组的一些常用操作是很有必要的。1、数组去重1、from()叠加newSet()方法字符串或数值型数......
  • Selenium4+Python3系列(十) - Page Object设计模式
    前言PageObject(PO)模式,是Selenium实战中最为流行,并且被自动化测试同学所熟悉和推崇的一种设计模式之一。在设计测试时,把页面元素定位和元素操作方法按照页面抽象出来,分离成......
  • Python 爬取单个网页所需要加载的URL地址和CSS、JS文件地址
    直接上代码:脱敏后自用的py采集代码,#!/usr/bin/envpython#-*-coding:utf-8-*-"""@author:Andy@file:xxx.py@time:下午05:50@desc:采集的文章数据进博客"""im......
  • 设计模式之命令模式
    概述在软件开发中,经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收者是谁,也不知道被请求的操作是哪个,此时,特别希望能够以一种松耦合的方式来设......
  • 运行 JavaScript 代码片段
    原文链接​​RunsnippetsofJavaScript​​--作者​​KayceBasques​​&​​SofiaEmelianova​​如果你发现自己反复使用​​Console​​来运行同一份代码,那么......