定义

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

详细描述

在平时开发中来说有些对象或者操作只需要一个(比如事件的绑定,dom节点的创建又或者页面或者组件的创建、事件绑定等),所以这个时候就需要使用单例模式来时所需要的操作只执行一次类节省不必要的开销和资源。

代码实现

因为在js中生成一个对象不需要非得使用一个类进行创建,所以我们只需要保证所创建的对象只有一个并且全局可以访问就可以。因此我们创建类的方式可以采用new 方式也可以采用函数方式,又或者直接定义出来,然后将它缓存起来不被重复创建就可以。下面我们将采用闭包和高阶函数来实现一个js中的单例模式。 代码如下:

    /***** @param {*} fn 创建对象的函数* @return {*} */const single = (fn) => {let instance; // 缓存唯一对象的变量return function(...res) {/* 如果没创建过对象则调用传入的函数创建并缓存,如果已经存在创建好的对象直接返回即可。注意: js中创建对象不一定基于类,所以可以采用函数创建的方式,如果想基于类的方式创建,那么fn参数传入构造函数,然后使用new 关键字进行调用生成即可。*/if (!instance) instance = fn.apply(this, res);return instance;}}

上述代码根据单例模式的定义和思想,实现一个基于js语言特点更加通用的单例模式,使用的时候只需要将生成对象的函数传进去即可。

测试

function domObj (text) {const div = document.createElement('div');div.innerText = text;document.body.appendChild(div);return div;
}const singleDom = single(domObj);console.log(singleDom('hello') === singleDom('world')); // true

应用

1、 创建登录浮框、蒙层、消息弹框、动态元素、组件等都可以使用单例模式进行创建,因为他们在使用的时候都是唯一的,只需使用的时候创建一次就行,不需要重复创建较少系统的性能开销,下面就实现一个唯一的内容展示框,代码如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div><button onclick="hanldleClick('block')">显示</button><button onclick="hanldleClick('none')">隐藏</button></div><script>const single = (fn) => { // 单例let instance;return function(...res) {if (!instance) instance = fn.apply(this, res);return instance;}}function creatObj() { // 动态创建元素对象const dom = document.createElement('div');dom.innerText = '我是展示的内容';dom.style.display = 'none';document.body.appendChild(dom);return dom;}const singleDom = single(creatObj);function hanldleClick (data) { // 响应点击事件const dom = singleDom();dom.style.display = data;}</script>
</body>
</html>

上述代码就创建了一个唯一的展示内容的节点,不管隐藏还是显示,它只会创建一次。

2、 绑定一次事件。 有时候我们渲染完页面的一个列表后会给这个列表添加点击事件,但是列表的数据是通过ajax多次动态追加的,我们其实只需要在第一次渲染列表的时候添加一次事件即可,如果不想记录当前是否是第一次渲染列表,也可以使用单例模式来实现,代码如下:

    const single = (fn) => { // 单例let instance;return function(...res) {if (!instance) instance = fn.apply(this, res);return instance;}}const render = single(function() { // 绑定事件函数console.log('绑定事件');  // 只会执行一次document.getElementById('list').onclick = function() {console.log('click');}return true;});render();render();render();render();

总结

在js中严格来说其实是没有类这个概念的,他的类是基于原型模式来实现的,所以它的单例模式又和其他语言(只能由类来创建对象的语言,如java)不太一样,所以我们需要灵活借用单例模式的思想,来优化和实现我们的功能和业务,而不能生搬整个模式。

js中的设计模式之单例模式相关推荐

  1. js中的设计模式之组合模式

    Js中的组合模式 定义 是一种将对象组合成树状结构的层次结构模式,用来表示 整体-部分 的关系,使用用户对单个对象和组合对象具有一致的访问性. 详细描述 组合模式是一个树形结构,里面的数据可以是单个对 ...

  2. js中的设计模式之享元模式

    js中的享元模式 定义 运用共享技术有效支持大量细粒度的对象,以减少对象的创建数量来减少内存的占用提高性能. 详细描述 享元模式的核心就是共享,当在项目开发中创建了太多的对象,而这些对象还有很多相似之 ...

  3. Nest.js中的设计模式——装饰器

    背景 Nest是围绕一种称为装饰器的语言特性构建的. 装饰器风格的实现 Nest在面向对象设计中用到了装饰器模式去组织代码. 装饰器模式是一种动态地往一个类别中添加新的行为的设计模式 在写项目的时候, ...

  4. js中的设计模式之中介者模式

    Js中的中介者模式 定义 定义一个中介者对象来封装一系列对象的交互,把一批原来交互关系复杂的对象转换成一组松散耦合的对象,使他们变得易于维护和修改. 详细描述 在我们开发中经常会将对象拆分为更小的颗粒 ...

  5. 【深入设计模式】单例模式—从源码分析内部类单例、枚举单例以及单例模式在框架中的应用

    文章目录 1. 使用静态内部类实现单例模式 1.1 静态内部类单例写法 1.2 如何实现懒加载 1.3 为什么线程安全 2. 枚举类型单例单例模式 2.1 枚举类型单例写法 2.2 枚举类型单例原理 ...

  6. JS设计模式初探——单例模式

    title:设计模式之--单例模式 categories:tech tag:[设计模式,编程] 模式名称 ​ 所谓单例,即整个系统中只存在某个类的一个单一实例. 解决的问题(应用场景) ​ 单例模式是 ...

  7. js架构设计模式——由项目浅谈JS中MVVM模式

    1.    背景 最近项目原因使用了durandal.js和knockout.js,颇有受益.决定写一个比较浅显的总结. 之前一直在用SpringMVC框架写后台,前台是用JSP+JS+标签库,算是很 ...

  8. js最简单的几个特效_高阶函数不会用?教你JS中最实用的几个高阶函数用法

    不废话,先来看下什么是高阶函数 高阶函数 函数可以作为参数传递 函数可以作为返回值输出 函数作为参数传递 回调函数 在ajax异步请求的过程中,回调函数使用的非常频繁 在不确定请求返回的时间时,将ca ...

  9. JavaScript 中的设计模式

    目录 1. 单例模式 2. 策略模式 3. 代理模式 4. 装饰者模式 5. 组合模式 6. 工厂模式 7. 访问者模式 8. 发布订阅模式 9. 观察者模式 10. 参考链接 设计模式(Design ...

  10. JS —— 6、设计模式、设计模式分析、组件封装、ES6

    目录 28.设计模式 (1)观察者模式 (2)代理模式 (3)工厂模式 (4)单例模式 (5)适配器模式 (6)装饰器模式 29.设计模式分析 30.组件封装 (1)封装好处 (2)HttpAjax组 ...

最新文章

  1. sybase Invalid command line argument 'and'.
  2. 打不开_网页打不开,怎解?
  3. 四川大学c语言期末试题答案,四川大学计算机学院2005级C语言程序设计试卷(2份,有答案)...
  4. ??征集Sql Server2005设置Windows集成认证资料
  5. IDC_EDIT控件输入数字改变IDC_SCROLLBAR滑块位置
  6. IOS单例的两种实现方式
  7. Spring AOP中定义切点(PointCut)和通知(Advice)
  8. VScode使用python的yapf库
  9. boost::system::generic_category相关的测试程序
  10. 从 0 到 300,Instagram 创始人 CTO 分享工程团队成长的经验
  11. 凸透镜成像动画可拖动_光学实验二:探究凸透镜成像规律
  12. java 数组大数乘法_java – 在数组中查找3个数字的最大乘积
  13. 如何利用图像识别、语音识别、文本挖掘做好鉴黄?
  14. 20165301课下作业
  15. 错误解决办法:‘NULL’ was not declared in this scope
  16. java基础-基础类型包装类型
  17. VassistX的简单介绍与下载安装
  18. ffmpeg 用 -ss指定起始时间
  19. u盘写保护无法格式化的修复
  20. UVALive - 7345 The Hypnotic Spirals 高等数学+几何知识

热门文章

  1. phpexcel 导入数据 Invalid cell coordinate
  2. 小白跑WRF第五天,安装WPS和静态地理数据
  3. 三星t750c android6,BlueFrag:Android 蓝牙零交互远程代码执行漏洞分析 - 嘶吼 RoarTalk – 回归最本质的信息安全,互联网安全新媒体,4hou.com...
  4. Flutter的生命周期
  5. B站html5直播黑屏,b站H5播放器改版后失效 · Issue #777 · the1812/Bilibili-Evolved · GitHub...
  6. tableau实战系列(十二)-使用盒须图查看你的数据分布
  7. Node中间件multer库学习
  8. 【读书笔记】《向上管理:如何正确汇报工作》
  9. android MediaRecorder录屏时带录音功能实现
  10. html-box-sizing