当前位置: 首页 > news >正文

js设计模式-工厂模式 单例模式 观察者模式 发布订阅模式 原型模式 代理模式 迭代器模式

1 工厂模式

// 工厂模式: 调用函数返回对象function factory(name, age){return {name: name,age: age}
}const person1 = factory('Tom', 18);
// 类似的库使用工厂函数的有: jQuery, React.createElement,axios.create,vue.createApp等

2 单例模式

// 单例模式:单例方法返回唯一实例 单例模式的核心是确保只有一个实例,并提供全局访问
// 单例模式实现class SingleTon {static #instance = null;static getInstance(){if(!this.#instance){this.#instance = new SingleTon();}return this.#instance;}
}
// 这是单例模式的方法
const singleTon1 = SingleTon.getInstance();
const singleTon2 = SingleTon.getInstance();
console.log(singleTon1 === singleTon2); // true
// 类似的库使用单例模式的有: vue.use vant中的notify等

3 观察者模式

// 观察者模式:一个对象可能有一个或多个观察者,当对象状态发生变化时,会通知所有观察者(执行对应的回调)
// 最典型的例子是DOM事件 如下就是一个简单的观察者模式
const button = document.getElementById('button');
button.addEventListener('click', function(){console.log('click');
})
// 可以有多个事件监听器(观察者)
button.addEventListener('click', function(){console.log('click2');
})

4 发布订阅模式

// 发布订阅模式:发布者和订阅者之间没有直接联系,通过第三方来实现调度(事件总线)
// 一般来说有四种行为 $on注册事件 $off清除事件 $emit触发时间 $once仅触发一次
// 现在简单的实现一个发布订阅模式
class MygoEventBus{#handlers = {}$on(event, callback){if(!this.#handlers[event]){this.#handlers[event] = []}this.#handlers[event].push(callback)}$emit(event, ...args){this.#handlers[event] ||  (this.#handlers[event] = [])this.#handlers[event].forEach(callback => {callback(...args)})}$off(event){this.#handlers[event] = undefined}$once(event, callback){this.$on(event, (...args) => {callback(...args)this.$off(event)})}
}// 测试代码
const bus = new MygoEventBus();
bus.$on('click', function(){console.log('click');
})
bus.$on('click', function(){console.log('click2');
})
bus.$emit('click');
bus.$emit('click');
bus.$off('click');
bus.$emit('click');
bus.$once('click', function(){console.log('click3');
})
bus.$emit('click');
bus.$emit('click');
// 输出结果为 click click2 click click2 click3

5 原型模式

// 原型模式:类似于使用object.create()方法创建对象
// 通过原型模式创建对象
const person = {name: 'Tom',age: 18
}const person2 = Object.create(person);
// 再Vue中数组和对象的响应式原理就是通过原型模式实现的

6 代理模式

// 代理模式:代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问
// 下面举例一个应用场景(类似于DNS查找)就是数据缓存中间件 代码如下:
class AreaData{cache = {}getAreaCode(code){if(!this.cache[code]){// 模拟请求数据console.log('请求数据')this.cache[code] = 'area' + code}return this.cache[code]}
}const areaData = new AreaData();
console.log(areaData.getAreaCode(1));
// 第二次请求数据时,直接返回缓存数据
console.log(areaData.getAreaCode(1));
console.log(areaData.getAreaCode(2));

7 迭代器模式

// 迭代器模式:只要一个对象实现了迭代器协议和next方法,就可以被for...of循环遍历
// 实现迭代器可以使用generator或者手动实现
// [Symbol.iterator]要求返回一个迭代器对象,迭代器对象要求有next方法,next方法返回一个对象,对象有value和done两个属性
const obj = {[Symbol.iterator]: () =>{function* gen(){yield 1;yield 2;yield 3;}return gen();}
}for(let item of obj){console.log(item); // 1 2 3
}// 手动实现迭代器
const obj2 = {data: [1, 2, 3],[Symbol.iterator]: function(){let index = 0;let that = this;return {next(){return {value: that.data[index],done: index++ === that.data.length}}}}
}for(let item of obj2){console.log(item); // 1 2 3
}// 迭代器模式模仿python中的range
function* range(end){for(let i = 0; i < end; i ++){yield i;}
}for(let item of range(10)){console.log(item); // 0 1 2 3 4 5 6 7 8 9
}

相关文章:

  • GPU参数指标
  • swiper.js实现跑马灯效果,无缝衔接,鼠标悬停
  • <<迷雾>> 第 3 章 怎样才能让机器做加法 示例电路
  • python程序操作Windows系统中的软件如word等(是否可以成功操作待验证)
  • 基于IAR平台的freertos移植
  • Mac电脑快速回复的神器-快捷短语
  • 华为交换机命名规则大详解,再也不愁选交换机了
  • 分层图 的尝试学习 1.0
  • 【C++】C++的Vector使用和实现
  • 软件架构设计师教程 第11章 11.4 边缘计算概述 笔记
  • neo4j小白入门
  • 询盘鸭独立站
  • OpenCV图像文件读写(4)解码图像数据函数imdecode()的使用
  • Rustrover2024.2 正式发布:个人非商用免费,泰裤辣
  • idea 创建多模块项目
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • [deviceone开发]-do_Webview的基本示例
  • 【划重点】MySQL技术内幕:InnoDB存储引擎
  • Angular 4.x 动态创建组件
  • Django 博客开发教程 16 - 统计文章阅读量
  • django开发-定时任务的使用
  • HTML中设置input等文本框为不可操作
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • php中curl和soap方式请求服务超时问题
  • python学习笔记-类对象的信息
  • RedisSerializer之JdkSerializationRedisSerializer分析
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • windows下如何用phpstorm同步测试服务器
  • 模型微调
  • 前端知识点整理(待续)
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • 新版博客前端前瞻
  • #在 README.md 中生成项目目录结构
  • (11)iptables-仅开放指定ip访问指定端口
  • (13)Hive调优——动态分区导致的小文件问题
  • (2024,LoRA,全量微调,低秩,强正则化,缓解遗忘,多样性)LoRA 学习更少,遗忘更少
  • (4.10~4.16)
  • (Forward) Music Player: From UI Proposal to Code
  • (ibm)Java 语言的 XPath API
  • (LLM) 很笨
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (教学思路 C#之类三)方法参数类型(ref、out、parmas)
  • (转)EOS中账户、钱包和密钥的关系
  • (转)IOS中获取各种文件的目录路径的方法
  • (转)利用ant在Mac 下自动化打包签名Android程序
  • (转)我也是一只IT小小鸟
  • .bat批处理(一):@echo off
  • .NET 4.0中的泛型协变和反变
  • .NET 8.0 中有哪些新的变化?
  • .NET(C#、VB)APP开发——Smobiler平台控件介绍:Bluetooth组件
  • .NET命令行(CLI)常用命令
  • /proc/stat文件详解(翻译)
  • @data注解_一枚 架构师 也不会用的Lombok注解,相见恨晚
  • @entity 不限字节长度的类型_一文读懂Redis常见对象类型的底层数据结构