前端也需 OOP 思维!面向过程 vs 面向对象开发,90% 的人没搞懂

前端也需 OOP 思维!面向过程 vs 面向对象开发,90% 的人没搞懂

前端也需 OOP 思维!面向过程 vs 面向对象开发,90% 的人没搞懂

今天遇到个挺有代表性的事:我吭哧吭哧写完一个需求,领导 review 代码时说:“你这是面向过程开发的,得用面向对象的思维来写。”

我当时就懵了——前端 JS/TS 里,面向过程和面向对象到底有啥区别?不都是写函数、调 API 吗?

直到我把两段代码摆在一起对比,才恍然大悟。


一个真实场景:用户订单处理

假设我们要处理用户订单,计算价格、验证库存、生成记录。

❌ 面向过程写法(我最初写的)

// 一堆函数,数据到处传递functioncalculateTotal(price:number, quantity:number, discount:number):number{return price * quantity *(1- discount);}functioncheckStock(productId:string, quantity:number):boolean{// 查询数据库或APIconst stock =getStockFromDB(productId);return stock >= quantity;}functioncreateOrder(userId:string, productId:string, quantity:number): Order {const price =getPrice(productId);const discount =getUserDiscount(userId);if(!checkStock(productId, quantity)){thrownewError('库存不足');}const total =calculateTotal(price, quantity, discount);return{ id:generateId(), userId, productId, quantity, total, createdAt:newDate()};}// 数据像皮球一样在函数间传来传去const order =createOrder('user123','product456',2);

面向过程的特点:

  1. 数据和行为分离:数据(price、quantity)和操作它们的函数是分开的
  2. 函数是主角:一切围绕函数展开
  3. 数据公开透明:谁都可以修改数据
  4. 顺序执行:像食谱一样,第一步、第二步…

✅ 面向对象写法(领导想要的)

classOrder{private id:string;private userId:string;private productId:string;private quantity:number;private total:number;private createdAt: Date;constructor(userId:string, productId:string, quantity:number){this.id =generateId();this.userId = userId;this.productId = productId;this.quantity = quantity;this.createdAt =newDate();this.validate();this.calculateTotal();}privatevalidate():void{if(!this.checkStock()){thrownewError('库存不足');}if(this.quantity <=0){thrownewError('数量必须大于0');}}privatecheckStock():boolean{const stock = StockService.getStock(this.productId);return stock >=this.quantity;}privatecalculateTotal():void{const price = ProductService.getPrice(this.productId);const discount = UserService.getDiscount(this.userId);this.total = price *this.quantity *(1- discount);}publicapplyCoupon(couponCode:string):void{const discount = CouponService.validate(couponCode);this.total *=(1- discount);}publicgetSummary(): OrderSummary {return{ id:this.id, productId:this.productId, quantity:this.quantity, total:this.total, createdAt:this.createdAt };}}// 使用:创建一个订单对象,一切都在对象内部处理const order =newOrder('user123','product456',2); order.applyCoupon('SAVE10');const summary = order.getSummary();

面向对象的特点:

  1. 数据和行为封装在一起:订单数据和处理订单的方法在一个类里
  2. 对象是主角:一切围绕对象展开
  3. 数据私有化:外部不能直接修改内部数据
  4. 对象自己负责自己:订单对象知道如何验证自己、计算自己的价格

核心区别:思维模式不同

面向过程:做事

“我要处理订单,先查价格,再查库存,然后计算总价…”

像在餐馆点餐:告诉厨师每一步要做什么。

面向对象:找对象

“我需要一个订单对象,它能自己验证、自己计算价格…”

像在餐馆吃饭:告诉服务员“来份牛排”,牛排怎么做是厨房的事。


4个具体对比,一看就懂

对比1:数据管理

// 面向过程:数据是公开的let user ={ name:'张三', age:25};functionupdateUserName(user, newName){ user.name = newName;// 直接修改}// 面向对象:数据是私有的classUser{private name:string;private age:number;publicsetName(newName:string):void{if(newName.length <2){thrownewError('姓名太短');}this.name = newName;// 通过方法修改,可以加验证}}

对比2:错误处理

// 面向过程:错误检查分散在各处functionprocessOrder(order){if(!order.user)return'用户不存在';if(!order.product)return'商品不存在';if(order.quantity <=0)return'数量错误';// ...}// 面向对象:错误检查在对象创建时classOrder{constructor(user, product, quantity){if(!user)thrownewError('用户不存在');if(!product)thrownewError('商品不存在');if(quantity <=0)thrownewError('数量错误');// 一次性检查完}}

对比3:功能扩展

// 面向过程:加功能就要改很多函数functioncalculateTotal(price, quantity, discount){// 突然要加会员折扣// 得修改这个函数,加参数、改逻辑}// 面向对象:加功能只需扩展类classOrder{calculateTotal(){let total =this.price *this.quantity; total *=(1-this.discount);// 加会员折扣很简单if(this.user.isVIP){ total *=0.9;}}}

对比4:代码组织

// 面向过程:按步骤组织代码// order.jsfunctionvalidateOrder(){/*...*/}functioncalculatePrice(){/*...*/}functioncheckStock(){/*...*/}functioncreateInvoice(){/*...*/}// 面向对象:按领域组织代码// Order.jsclassOrder{/* 订单相关的一切 */}// Product.js classProduct{/* 商品相关的一切 */}// User.jsclassUser{/* 用户相关的一切 */}

什么时候用哪种?别搞错

用面向过程 ✅

  1. 简单脚本:一次性的数据处理脚本
  2. 工具函数utils/helpers 里的纯函数
  3. 性能关键:需要极致性能的场景
  4. 函数式编程:数据不可变,函数是第一公民
// 工具函数适合面向过程exportfunctionformatDate(date: Date):string{return`${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()}`;}exportfunctiondebounce(fn:Function, delay:number):Function{let timer: NodeJS.Timeout;return(...args:any[])=>{clearTimeout(timer); timer =setTimeout(()=>fn(...args), delay);};}

用面向对象 ✅

  1. 复杂业务逻辑:电商、CRM、ERP 系统
  2. 状态丰富的对象:用户、订单、商品
  3. 需要封装和隐藏细节:支付、权限等敏感操作
  4. 容易扩展的系统:需要经常加新功能
// 电商系统适合面向对象classShoppingCart{private items: CartItem[]=[];private userId:string;publicaddItem(product: Product, quantity:number):void{// 验证、计算、更新一气呵成}publiccheckout(): Order {// 复杂的结账逻辑封装在里面}publicgetRecommendations(): Product[]{// 基于用户历史的推荐}}

前端特有的考量

在前端,我们还要考虑这些:

React 组件:其实是面向对象的

// React 组件本质上是对象(有状态、生命周期)classUserProfileextendsReact.Component {constructor(props){super(props);// 初始化this.state ={ user:null};// 封装状态}componentDidMount(){this.loadUser();// 行为}loadUser=async()=>{const user =await api.getUser(this.props.userId);this.setState({ user });// 修改状态}render(){returnthis.state.user ?(<div>{this.state.user.name}</div>):null;}}

Vue 3 Composition API:两者结合

// 组合式函数(像面向过程)functionuseUser(userId:string){const user =ref<User |null>(null);asyncfunctionloadUser(){ user.value =await api.getUser(userId);}return{ user, loadUser };}// 但在组件中使用时(像面向对象)exportdefaultdefineComponent({setup(props){// 逻辑组合在一起const{ user, loadUser }=useUser(props.userId);const{ orders, loadOrders }=useOrders(props.userId);return{ user, orders, loadUser, loadOrders };}});

如何从面向过程转到面向对象?

如果你习惯了面向过程,可以这样过渡:

第1步:识别“名词”

看你的代码,找出主要的名词(用户、订单、商品),这些就是潜在的类。

第2步:封装数据

把散落在各处的相关数据,包装到一个类里。

第3步:归并行为

把操作这些数据的函数,变成类的方法。

第4步:设定边界

决定哪些公开(public),哪些私有(private)。

重构示例

// 之前:数据和行为分散let cartItems =[];functionaddToCart(item){/*...*/}functioncalculateTotal(){/*...*/}functionapplyDiscount(){/*...*/}// 之后:封装成类classShoppingCart{private items: CartItem[]=[];publicaddItem(item: CartItem):void{/*...*/}privatecalculateTotal():number{/*...*/}publicapplyDiscount(code:string):void{/*...*/}}

领导到底在说什么?

当领导说“要用面向对象思维”时,他其实在说:

  1. 封装性:“别让外部随便改数据”
  2. 职责清晰:“一个类只做一件事”
  3. 易扩展:“加功能别影响老代码”
  4. 易维护:“出了问题知道去哪儿找”

这不是在批评你代码写得不好,而是在教你写出更容易维护、更容易扩展的代码。


最后的大实话

在前端开发中,没必要所有代码都面向对象。好的做法是:

  • 业务核心逻辑用面向对象(封装、易维护)
  • 工具函数/UI逻辑用面向过程(简单、直接)
  • 状态管理用函数式(可预测、易测试)

就像做菜一样,面向过程是菜谱(先放油,再放菜),面向对象是预制菜(加热就能吃)。

关键是根据场景选对方法。今天你知道区别了,下次领导再提,你不仅能改,还能跟他讨论哪种更适合。

记住:最好的代码不是“最面向对象”的代码,而是最适合当前需求的代码

Read more

AI入门系列:AI新手必看:人工智能发展历程与现状分析

AI入门系列:AI新手必看:人工智能发展历程与现状分析

写在前面:为什么AI发展历史很重要? 记得刚开始学习AI的时候,我总觉得历史这种东西很枯燥,不如直接学习最新的技术来得实在。但后来我发现,了解AI的发展历程,就像了解一个人的成长经历一样,能帮助我们更好地理解现在的AI是如何走到今天的,也能帮助我们预测未来可能的发展方向。 有一次,我和一位从事AI研究多年的教授聊天,他告诉我:"现在的学生总想直接学习深度学习,但如果不了解符号主义AI的兴衰,就无法理解为什么深度学习会成功,也无法预见它可能面临的挑战。"这句话让我深受启发。 所以,在这篇文章中,我想和大家一起回顾一下AI的发展历程,不是为了考试背诵那些枯燥的年代和事件,而是为了让我们能够站在历史的高度,更好地理解现在的AI技术,以及它在我们生活中的应用。 人工智能的诞生:一个充满想象力的开始 说起AI的诞生,我们不得不提到1956年的达特茅斯会议。这次会议被公认为人工智能学科的诞生标志。 想象一下那个场景:一群来自不同领域的顶尖科学家,包括约翰·麦卡锡、马文·明斯基、克劳德·香农等,聚集在一起,讨论着一个看似疯狂的问题:"机器能思考吗?"他们相信,只要给机器输入足够多的规则

技术拆解:P2P组网如何一键远程AI

技术拆解:P2P组网如何一键远程AI

文章目录 * **远程访问AI服务的核心是什么?** * **从暴露服务到连接设备** * **核心组件与交互解析** * **安全架构深度剖析** * **一键安装脚本的技术实现** * **# Windows** * **#macOS** * **#Linux** * **与AI工作流的结合实践** 远程访问AI服务的核心是什么? 你自己在电脑或者服务器上装了AI服务,比如大语言模型、Stable Diffusion这些,但是有个头疼的事儿:外面的人或者你在别的地方,怎么既安全又方便地连上这些本地的服务?以前的办法要么得有公网IP,还得敲一堆命令行用SSH隧道,要么就是直接开端口映射,等于把服务直接晾在公网上,太不安全了。 今天咱们就好好说说一种靠P2P虚拟组网的办法,还拿个叫节点小宝的工具举例子,看看它怎么做到不用改啥东西,点一下就装好,还能建个加密的通道,实现那种“服务藏得好好的,想连就能直接连上”的安全远程访问方式。 从暴露服务到连接设备 核心思路转变在于:不再尝试将内网服务端口暴露到公网(一个危险的攻击面),而是将外部访问设

人工智能:自然语言处理在教育领域的应用与实战

人工智能:自然语言处理在教育领域的应用与实战

人工智能:自然语言处理在教育领域的应用与实战 学习目标 💡 理解自然语言处理(NLP)在教育领域的应用场景和重要性 💡 掌握教育领域NLP应用的核心技术(如智能问答、作业批改、个性化学习) 💡 学会使用前沿模型(如BERT、GPT-3)进行教育文本分析 💡 理解教育领域的特殊挑战(如多学科知识、学生认知差异、数据隐私) 💡 通过实战项目,开发一个智能问答系统应用 重点内容 * 教育领域NLP应用的主要场景 * 核心技术(智能问答、作业批改、个性化学习) * 前沿模型(BERT、GPT-3)在教育领域的使用 * 教育领域的特殊挑战 * 实战项目:智能问答系统应用开发 一、教育领域NLP应用的主要场景 1.1 智能问答 1.1.1 智能问答的基本概念 智能问答是通过自然语言与用户进行交互,回答用户问题的程序。在教育领域,智能问答的主要应用场景包括: * 课程问答:回答课程相关的问题(如“什么是机器学习”

AI时代人人都是产品经理:落地流程:AI 核心功能,从需求到上线的全流程管控方法

AI时代人人都是产品经理:落地流程:AI 核心功能,从需求到上线的全流程管控方法

AI的普及正在重构产品经理的工作模式——不再依赖传统的跨部门协作瓶颈,AI可以成为产品经理的"全职助手",覆盖需求分析、原型设计、开发协同、测试验证全流程。本文将拆解AI时代产品核心功能从0到1落地的完整管控方法,让你用AI能力提升300%的落地效率。 一、需求阶段:AI辅助的需求挖掘与标准化 需求是产品的起点,AI可以帮你从海量信息中精准定位用户真实需求,避免"伪需求"浪费资源。 1. 需求挖掘:AI辅助用户洞察 传统需求调研依赖问卷、访谈,效率低且样本有限。AI可以通过以下方式快速完成用户洞察: * 结构化处理非结构化数据:用AI分析用户在社交媒体、客服对话、应用评论中的碎片化反馈,自动提炼高频需求点 * 需求优先级排序:基于KANO模型,AI可以自动将需求划分为基础型、期望型、兴奋型、无差异型四类,输出优先级列表 实战工具与示例: 使用GPT-4+Python脚本批量处理应用商店评论: import openai import pandas as