1 工厂模式
javascript
复制代码
// 工厂模式: 调用函数返回对象
function factory(name, age){
return {
name: name,
age: age
}
}
const person1 = factory('Tom', 18);
// 类似的库使用工厂函数的有: jQuery, React.createElement,axios.create,vue.createApp等
2 单例模式
javascript
复制代码
// 单例模式:单例方法返回唯一实例 单例模式的核心是确保只有一个实例,并提供全局访问
// 单例模式实现
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 观察者模式
javascript
复制代码
// 观察者模式:一个对象可能有一个或多个观察者,当对象状态发生变化时,会通知所有观察者(执行对应的回调)
// 最典型的例子是DOM事件 如下就是一个简单的观察者模式
const button = document.getElementById('button');
button.addEventListener('click', function(){
console.log('click');
})
// 可以有多个事件监听器(观察者)
button.addEventListener('click', function(){
console.log('click2');
})
4 发布订阅模式
javascript
复制代码
// 发布订阅模式:发布者和订阅者之间没有直接联系,通过第三方来实现调度(事件总线)
// 一般来说有四种行为 $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 原型模式
javascript
复制代码
// 原型模式:类似于使用object.create()方法创建对象
// 通过原型模式创建对象
const person = {
name: 'Tom',
age: 18
}
const person2 = Object.create(person);
// 再Vue中数组和对象的响应式原理就是通过原型模式实现的
6 代理模式
javascript
复制代码
// 代理模式:代理模式是为一个对象提供一个代用品或占位符,以便控制对它的访问
// 下面举例一个应用场景(类似于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 迭代器模式
javascript
复制代码
// 迭代器模式:只要一个对象实现了迭代器协议和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
}