JavaScript 前端设计模式 | 青训营笔记

69 阅读2分钟

这是我参与「第四届青训营」笔记创作活动的的第 4 天

23 种设计模式

  • 创建型:如何创建一个对象
  • 结构型:如何灵活地将对象组装成较大的结构
  • 行为型:负责对象间的搞笑通信和职责划分

浏览器中的设计模式

单例模式

存在一个全局唯一访问的对象,在全局人任意地方访问到的都是同一个对象,其中最常见的就是浏览器中的 window

应用场景

全局的缓存、全局状态管理等。

单例模式实现请求缓存的栗子

import { api } from './utils';

const cache: Record<string, string> = {};

export const request = async (url: string) => {
    if (cache[url]) return cache[url];
    const response = await api(url);
    return (cache[url] = response);
}

这样的话如果我们请求同一个地址多次,第一次会进行请求并缓存到 cache 变量中,而后续的相同地址的请求会直接从缓存中读取。

发布订阅模式

发布订阅模式是一种订阅机制,可在被订阅对象发生变化时通知订阅者。

应用场景

从系统架构之间的解耦,到业务中一些实现模式,如邮件订阅,上线订阅等。

JavaScript 中的 addEventListener 就是一种发布订阅模式,旨在触发事件的时候能够触发对应的事件监听器。

JavaScript 中的设计模式

原型模式

原型模式是指复制已有的对象来创建新的对象。

在 JavaScript 中,可以使用 Object.create(protoObject) 来基于创建一个基于 protoObject 的新对象。

代理模式

可以自定义控制原对象的访问方式,并且允许在更新的前后做一定的处理。

JavaScript 中可以使用 Proxy 来实现对对象的代理。

new Proxy(originObject, {
    set: () => {},
    // ...
})

应用场景

监控,代理工具,前端框架实现等。

Vue3 就是使用代理来实现自动更新 DOM。

迭代器模式

迭代器模式旨在不暴露数据类型的情况下访问集合中的数据。

在 JavaScript 中可以为一个对象定义 Symbol.iterator 生成器函数来使得对象可以被迭代。

myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
    yield 3;
};

总结

  • 总结出抽象的模式相对比较简单,但是想要将抽象的模式套用到场景中却非常困难。
  • 现在编程语言的多变成范式带来的更多可能性。
  • 真正优秀的开源项目学习设计模式并不断实践。

因此设计模式并不是银弹,我们要学习的是设计模式中的思想。

参考

  • 字节跳动青训营 - 前端设计模式应用
  • mdn web docs