面试之《前端常见的设计模式》

前端开发中运用多种设计模式可以提高代码的可维护性、可扩展性和可复用性。以下是一些常见的前端设计模式:

创建型模式

1. 单例模式
  • 定义:确保一个类只有一个实例,并提供一个全局访问点。
  • 应用场景:在前端中,像全局状态管理对象、数据库连接对象等通常使用单例模式。例如,在 React 项目中使用 Redux 管理全局状态,Redux 的 store 就是一个单例,整个应用只有一个 store 实例。
  • 示例代码(JavaScript)
class Singleton {constructor() {if (!Singleton.instance) {this.data = [];Singleton.instance = this;}return Singleton.instance;}addItem(item) {this.data.push(item);}getData() {return this.data;}
}
const singleton1 = new Singleton();
const singleton2 = new Singleton();
console.log(singleton1 === singleton2); // true
2. 工厂模式
  • 定义:定义一个创建对象的接口,让子类决定实例化哪个类。
  • 应用场景:当创建对象的逻辑比较复杂时,使用工厂模式可以将对象的创建和使用分离。例如,在创建不同类型的弹窗组件时,可以使用工厂模式根据不同的参数创建不同样式和功能的弹窗。
  • 示例代码(JavaScript)
class Button {constructor(text) {this.text = text;}render() {return `<button>${this.text}</button>`;}
}class Link {constructor(text, url) {this.text = text;this.url = url;}render() {return `<a href="${this.url}">${this.text}</a>`;}
}class ElementFactory {createElement(type, ...args) {if (type === 'button') {return new Button(...args);} else if (type === 'link') {return new Link(...args);}return null;}
}const factory = new ElementFactory();
const button = factory.createElement('button', 'Click me');
const link = factory.createElement('link', 'Google', 'https://www.google.com');
console.log(button.render());
console.log(link.render());

结构型模式

1. 装饰器模式
  • 定义:动态地给一个对象添加一些额外的职责。
  • 应用场景:在前端中,常用于给组件添加额外的功能,如添加样式、事件处理等。例如,在 React 中可以使用高阶组件(HOC)来实现装饰器模式,给组件添加日志记录、权限验证等功能。
  • 示例代码(JavaScript)
function logDecorator(component) {return class extends React.Component {componentDidMount() {console.log('Component mounted');}render() {return <component {...this.props} />;}};
}class MyComponent extends React.Component {render() {return <div>My Component</div>;}
}const DecoratedComponent = logDecorator(MyComponent);
2. 代理模式
  • 定义:为其他对象提供一种代理以控制对这个对象的访问。
  • 应用场景:在前端中,常用于处理图片懒加载、数据缓存等。例如,使用代理对象来控制对图片资源的访问,当图片进入可视区域时再加载真实的图片资源。
  • 示例代码(JavaScript)
class Image {constructor(src) {this.src = src;this.loadImage();}loadImage() {console.log(`Loading image from ${this.src}`);}display() {console.log(`Displaying image from ${this.src}`);}
}class ProxyImage {constructor(src) {this.src = src;this.realImage = null;}display() {if (!this.realImage) {this.realImage = new Image(this.src);}this.realImage.display();}
}const proxy = new ProxyImage('https://example.com/image.jpg');
proxy.display();

行为型模式

1. 观察者模式
  • 定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。
  • 应用场景:在前端中,常用于实现事件系统、状态管理等。例如,在 Vue.js 中,响应式原理就是基于观察者模式实现的,当数据发生变化时,会自动更新与之绑定的 DOM 元素。
  • 示例代码(JavaScript)
class EventEmitter {constructor() {this.events = {};}on(eventName, callback) {if (!this.events[eventName]) {this.events[eventName] = [];}this.events[eventName].push(callback);}emit(eventName, ...args) {if (this.events[eventName]) {this.events[eventName].forEach(callback => callback(...args));}}off(eventName, callback) {if (this.events[eventName]) {this.events[eventName] = this.events[eventName].filter(cb => cb!== callback);}}
}const emitter = new EventEmitter();
const callback = (message) => {console.log(`Received message: ${message}`);
};
emitter.on('message', callback);
emitter.emit('message', 'Hello, world!');
emitter.off('message', callback);
emitter.emit('message', 'This message won\'t be received.');
2. 状态模式
  • 定义:允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
  • 应用场景:在前端中,常用于实现组件的不同状态切换,如按钮的不同状态(正常、禁用、加载中)。
  • 示例代码(JavaScript)
class ButtonState {constructor(button) {this.button = button;}click() {}render() {}
}class NormalState extends ButtonState {click() {console.log('Button clicked');}render() {return '<button>Normal</button>';}
}class DisabledState extends ButtonState {click() {console.log('Button is disabled');}render() {return '<button disabled>Disabled</button>';}
}class Button {constructor() {this.state = new NormalState(this);}setState(state) {this.state = state;}click() {this.state.click();}render() {return this.state.render();}
}const button = new Button();
button.click();
button.setState(new DisabledState(button));
button.click();

以上只是前端开发中常见的一些设计模式,实际应用中可以根据具体需求选择合适的设计模式来优化代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72130.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity Android出包

Unity Android出包 1.Android Studio版本 不能高于Unity的版本 2.so库 这个库需要自己拷贝到Android工程当中 3.JDK版本太老 编译可以正常&#xff0c;但无法运行 File->ProjectStructure->SDK Location->Gradle Setting->Gradle JDK->X:/Android Stuido/jre …

Android 中临时文件存放路径选择

在 Android 中&#xff0c;下载临时文件通常可以放在以下目录中&#xff0c;具体选择取决于应用的需求和目标 Android 版本的限制&#xff1a; 1. 通用临时目录&#xff08;/data/local/tmp/&#xff09; 这是 Android 系统提供的一个通用临时目录&#xff0c;适用于存储临时…

【软件测试】--面试

准备简历–面试邀请 投递简历 面试&#xff08;笔试&#xff0c;HR面试&#xff0c;技术官面试&#xff09; 入职准备&#xff08;体检&#xff0c;背调&#xff09; 办理入职&#xff08;签合同&#xff09; 入职培训 试用期 转正 【简历要点】 1.基本信息 学校专业&#xff…

C盘清理技巧分享:释放空间,提升电脑性能

目录 1. 引言 2. C盘空间不足的影响 3. C盘清理的必要性 4. C盘清理的具体技巧 4.1 删除临时文件 4.2 清理系统还原点 4.3 卸载不必要的程序 4.4 清理下载文件夹 4.5 移动大文件到其他盘 4.6 清理系统缓存 4.7 使用磁盘清理工具 4.8 清理Windows更新文件 4.9 禁用…

rpm安装nux-dextop时出现 epel-release is needed的解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

qt加载VeloView工程

接上一篇点云软件配置与编译&#xff0c;使用qt加载需要先完成编译。编译完成后到编译目录下lidarview-superbuild\common-superbuild\lidarview\build 找到CmakeCache.txt&#xff0c;如下是我的编译目录。 使用QT6.5.3加载了CmakeCache.txt&#xff0c;QT5.14还加载不了cmake…

python编写的一个打砖块小游戏

游戏介绍 打砖块是一款经典的街机游戏&#xff0c;玩家控制底部的挡板&#xff0c;使球反弹以击碎上方的砖块。当球击中砖块时&#xff0c;砖块消失&#xff0c;球反弹&#xff1b;若球碰到挡板&#xff0c;则改变方向继续运动&#xff1b;若球掉出屏幕底部&#xff0c;玩家失…

git 基本常用操作,切换分支,合并分支

分支 two 查看所有分支 git branch 切换分支&#xff08;two&#xff09; git checkout two 创建并切换到新分支&#xff08;two&#xff09; git checkout -b two 提交当前代码到到源分支 git push --set-upstream origin two 合并分支 1. 切换到目标分支 例如&#xff0c;…

【QT】事件系统入门——QEvent 基础与示例

一、事件介绍 事件是 应用程序内部或者外部产生的事情或者动作的统称 在 Qt 中使用一个对象来表示一个事件。所有的 Qt 事件均继承于抽象类 QEvent。事件是由系统或者 Qt 平台本身在不同的时刻发出的。当用户按下鼠标、敲下键盘&#xff0c;或者是窗口需要重新绘制的时候&…

自然语言处理初学者指南

文章目录 一、说明二、自然语言处理发展史2.1 最早的自然语言处理简介2.2 历史2.3 NLP 的早期工作 三、NLP的现代方法3.1 单词编码3.2 循环神经网络3.3 强化学习3.4 深度学习 四、更进一步的方法 一、说明 对于初学者来说&#xff0c;自然语言处理的发展历史非常有必要了解&am…

unittest vs pytest区别

unittest vs pytest 对比 ​unittest 像“手动挡汽车”&#xff1a;操作步骤多&#xff0c;规则严格&#xff0c;适合老司机。​pytest 像“自动挡汽车”&#xff1a;开起来轻松&#xff0c;功能强大&#xff0c;适合新手和高效开发。 区别点​unittest​&#xff08;你学过的&…

CT117E-M4 CubeMX与Keil5 MDK-ARM基础配置

目录 1.CubeMX构建项目 2.芯片时钟配置 2.1 芯片引脚配置 2.2 时钟树配置 3.调试接口配置 4.项目管理器Project Manager配置 4.1 project 4.2 Code Generator 5. 生成代码 6.MDK_ARM配置 6.1 编译器选择 ​6.2 调试器配置 7. 创建本地代码文件夹 8. #include 路径…

MySQL中有哪几种锁?

大家好&#xff0c;我是锋哥。今天分享关于【MySQL中有哪几种锁&#xff1f;】面试题。希望对大家有帮助&#xff1b; MySQL中有哪几种锁&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 在MySQL中&#xff0c;锁是用来控制并发访问的机制&#xff0c;确…

MongoDB 和 Elasticsearch的区别、优缺点对比,以及选型建议

MongoDB 和 Elasticsearch 在存储和搜索方面各有特点&#xff0c;适用于不同的场景。以下是它们的区别、优缺点对比&#xff0c;以及选型建议。 1. 概述 MongoDB&#xff1a;分布式 NoSQL 文档数据库&#xff0c;基于 BSON&#xff08;类似 JSON&#xff09;的文档存储&#x…

55.HarmonyOS NEXT 登录模块开发教程(九):部署与发布

温馨提示&#xff1a;本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦&#xff01; HarmonyOS NEXT 登录模块开发教程&#xff08;九&#xff09;&#xff1a;部署与发布 效果预览 1. 引言 在前八篇教程中&#xff0c;我们介绍了H…

vue3实现跨页面缓存

避免频繁向后端发送请求,vue3中,可以用缓存机制,为了实现跨页面缓存,可以把缓存放到localsotrage里面 关键代码: const globalCache JSON.parse(localStorage.getItem(globalCache)) || {}; 然后加一个forceRefresh关键字, const fetchData async (forceRefresh false) …

c++类和对象(下篇)上

今天又重新回到c的学习中~在前两篇博客中,我简单的学习了类的定义,实例化,以及类中的默认成员函数.下篇是类和对象的收尾篇,在这篇中我将补充一下中篇所讲的构造函数以及介绍一些类和对象的新知识.下面让我们开始学习吧. 再谈构造函数 在之前我们实现构造函数时,初始化成员变量…

深度学习 bert流程

Token IDs 在自然语言处理任务中&#xff0c;特别是使用预训练模型如BERT时&#xff0c;文本首先通过一个分词器&#xff08;例如 BertTokenizer&#xff09;转换为一系列的token IDs。这些ID是每个词或子词单元在词汇表&#xff08;包含汉字、英文单词、标点符号&#xff09;…

PPT内视频播放无法播放的原因及解决办法

PPT内视频无法播放&#xff0c;通常是视频编解码的问题。目前我遇到的常见的视频编码格式有H.264&#xff0c;H.265&#xff0c;VP9&#xff0c;AV1这4种。H.264编解码的视频&#xff0c;Windows原生系统可以直接播放&#xff0c;其他的视频编码格式需要安装对应的视频编解码插…

星越L_行李舱空间拓展讲解

目录 1.储物槽 2.底板盖储物空间 3.挂钩 3.左侧照明灯 4.第二排座椅放倒 1.储物槽 使用钥匙或者后备箱按钮打开电动后备箱,左侧储物槽可储藏物品。 2.底板盖储物空间 打开地板盖,下方有储物空间。并放置了随车工具。 3.挂钩 后备箱左右两测各有一个挂钩。