这是我参与「第四届青训营 」笔记创作活动的的第1天
设计模式
浏览器中的设计模式
单例模式
定义:全局唯一访问对象
应用场景:缓存,全局状态管理等。eg. Window对象, 框架中的全局状态管理
实现数据缓存
// 使用类实现单例模式
import {api} from './util.js'
export class Request {
static instance: Request;
private cache: Record<string, string>;
constructor(){
this.cache = {};
}
static getInstance() {
if (this.instance) {
return this.distance;
}
this.instance = new Request();
return this.instance;
}
public async request(url: string){
if (this.cache[url]){
return this.cache[url];
}
const response = await api(url);
this.cache[url] = response;
return response;
}
}
// 使用全局变量实现单例模式
import {api} from './util.js'
const cache: Record<string, string> = {};
export const request = async(url: string) => {
if(cache[url]) {
return cache[url];
}
const response = await api(url);
cache[url] = response;
return response;
}
发布订阅模式
定义:一种订阅机制,可在被订阅对象发生变化时通知订阅者
应用场景:从系统架构之间的解耦,在业务中一些实现模式,像邮件订阅、上线订阅等等
type Notify = (user: User) => void;
export class User {
name: string;
status: "offline" | "online";
followers: {user: User; notify: Notify} [];
constructor(name: string) {
this.name = name;
this.status = "offline";
this.followers = [];
}
subscribe(user: User, notify: Notify) {
user.followers.push({user, notify});
}
online() {
this.status = "online";
this.followers.forEach(({notify}) => {
notify(this);
})
}
}
JavaScript中的设计模式
原型模式
定义:复制已有对象来创建新的对象
应用场景:js中对象创建的基本模式
Object.create(prototype, propertiesObject)
const baseUser: User = {
name: "",
status: "offline",
followers: [],
subscribe(user, notify){
user.followers.push({user, notify});
},
online(){
this.status = "online";
this.follower.forEach(({notify}) => {
notify(this);
});
}
}
export const createUser = (name: string) => {
const user: User = Object.create(baseUser);
user.name = name;
user.followers = [];
return user;
}
代理模式
定义:可自定义控制对原对象的访问方式,并允许在更新前后做一些二外处理
应用场景:监控,代理工具,前端框架实现等等
迭代器模式
定义:在不暴露数据类型的情况下访问集合中的数据 应用场景:数据结构中有多种数据类型,列表、树等,提供通用操作接口
class MyDomElement{
tag: string;
children: MyDomElement[];
constructor(tag: string){
this.tag = tag;
this.children = [];
}
addChildren(component: MyDomElement){
this.children.push(component);
}
[Symbol.iterator](){
const list = [...this.children];
let node;
return {
next: () => {
while((node = list.shift())) {
node.children.length > 0 && list.push(...node.children);
return {value: node, done: false};
}
return {value: null, done: true};
}
}
}
}
test("can iterate root element", () => {
const body = new MyDomElement("body");
const header = new MyDomElement("header");
const main = new MyDomElement("main");
const banner = new MyDomElement("banner");
const content = new MyDomElement("content");
const footer = new MyDomElement("footer");
body.addChildren(header);
body.addChildren(main);
body.addChildren(banner);
body.addChildren(content);
body.addChildren(footer);
// 此处可以使用for...of...进行遍历!!
const expectTags: string[] = [];
for (const element of body) {
if (element) {
expectTags.push(element.tag)
}
}
})
前端框架中的设计模式
代理模式
组合模式
定义:可多个对象组合使用,也可以单个对象独立使用 应用场景:DOM、前端组件、文件目录、部门