函数式编程vs面向对象编程vs过程式编程的JS演示比较
这是一个真实的例子,展示了三种最常见的编程范式的差异。我将用三种不同的方式解决一个问题。
每个示例将处理表单提交、验证用户输入并将创建的用户打印到控制台。我还添加了保存错误记录器。
案例表单!DOCTYPEhtmlhtmllangenheadmetacharsetUTF8metahttpequivXUACompatiblecontentIEedgemetanameviewportcontentwidthdevicewidth,initialscale1。0titleDocumenttitle!!!headbodybodyhtml
简单的HTML登录表单,它将包含三个js不同范式的有效文件。
过程化编程
过程式编程只是一步一步地解决问题。这是完全有效的编码方式,但是当您希望应用程序扩展时它有许多缺点。constformdocument。querySelector(form)constlogs〔〕form。addEventListener(submit,e{e。preventDefault()constusernamee。target。elements。username。valueconstpassworde。target。elements。password。valueleterrorif(username。trim()。length3)errorUsernamemustbeatleast3characterslongelseif(!password。match(〔09〕))errorPasswordmustcontainatleastonedigitif(error){logs。push(error)alert(error)return}constuser{username,password,}console。log(user)console。log(logs)})
简单一步一步解决问题。但它根本不可重用和可扩展。尽管它对于解决此类问题完全有效,并且您将看到它比其他问题要短得多。
面向对象编程
面向对象编程(OOP)是最接近现实世界的,因此很容易让您思考。我们查看将其划分为Object的代码,其中每个都只完成它的工作。在OOP中学习的有用概念是SOLID。ClassresponsibleonlyforloggingclassLogger{staticlogs〔〕staticshowAlert(message){this。logs。push(message)alert(message)}}ClassresponsibleonlyforvalidatinginputclassValidator{staticflags{minLength:MINLENGTH,hasDigit:HASDIGIT,}staticvalidate(value,flag,validatorValue){if(flagthis。flags。minLength){returnvalue。trim()。lengthvalidatorValue}if(flagthis。flags。hasDigit){returnvalue。match(〔09〕)}}}ClassresponsibleonlyforcreatingvaliduserclassUser{constructor(username,password){if(!Validator。validate(username,Validator。flags。minLength,3))thrownewError(Usernamemustbeatleast3characterslong)if(!Validator。validate(password,Validator。flags。hasDigit))thrownewError(Passwordmustcontainatleastonedigit)this。usernameusernamethis。passwordpassword}}ClassresponsibleonlyforfromhandlingclassFormHandler{constructor(formElement){this。formformElementthis。form。addEventListener(submit,this。handleSubmit。bind(this))}handleSubmit(e){e。preventDefault()constusernamee。target。elements。username。valueconstpassworde。target。elements。password。valuetry{constusernewUser(username,password)console。log(user)console。log(Logger。logs)}catch(err){Logger。showAlert(err)}}}constformdocument。querySelector(form)newFormHandler(form)
现在你可以明白我将问题划分为Objects的意思了:FormHandler是它自己的类,负责处理表单。User是另一个负责创建用户并使用Validator类验证输入的类。如果有错误,Logger类用于显示警报并保存日志。
正如你所看到的,有更多的代码,看起来更复杂那么为什么有人会喜欢这个?
酷的是,现在我们可以将它用于任何类似的形式,只需调用:newFormHandler(newform)
因此,它可以在包含此脚本的每个文件中重复使用。而且它很容易扩展,因为一切都被分成只做一件事的块(单一责任原则)。
函数式编程
非常流行,而且非常简单。请注意,这并不意味着它无论如何都更好。尽管某些范例可能对某些问题更好,但使用哪个完全取决于您。constFLAGS{minLength:MINLENGTH,hasDigit:HASDIGIT,}Functionthathandlesvalidationconstvalidate(value,flag,validatorValue){switch(flag){caseFLAGS。minLength:returnvalue。trim()。lengthvalidatorValuecaseFLAGS。hasDigit:return!!value。match(〔09〕)}}FunctionthatsetssubmithandlerconstsetFormSubmitHandler(formId,onSubmit){constformdocument。getElementById(formId)form。addEventListener(submit,onSubmit)}FunctionthatreturnsvaluesofrequiredfieldsasobjectInthiscaseitwillreturn{username:value,password:value}ItmightlookscarybutkeepinmindthatitscompletelyreusableconstgetFormValues(e,。。。fields){constvaluesObject。entries(e。target。elements)constfilteredValuesvalues。filter((〔key〕)fields。includes(key))returnfilteredValues。reduce((acc,〔key,{value}〕)({。。。acc,〔key〕:value}),{})}FunctionthatcreatesvaliduserconstcreateUser(username,password){if(!validate(username,FLAGS。minLength,3))thrownewError(Usernamemustbeatleast3characterslong)if(!validate(password,FLAGS。hasDigit))thrownewError(Passwordmustcontainatleastonedigit)return{username,password}}FunctionthatcreatesloggerobjectwithlogsandshowAlertfunctionconstlogger((){constlogs〔〕return{logs,showAlert:message{logs。push(message)alert(message)},}})()MainfunctionconsthandleSubmite{e。preventDefault()const{username,password}getFormValues(e,username,password)try{constusercreateUser(username,password)console。log(user)console。log(logger。logs)}catch(error){logger。showAlert(error)}}setFormSubmitHandler(userform,handleSubmit)
正如您在函数式编程中看到的,我们希望使用小的(理想情况下是纯函数)函数来解决问题。这种方法也非常具有可扩展性,并且函数可以重用。
纯函数是一种没有难以追踪的副作用的函数。纯函数应该只依赖于给定的参数。
结论
没有更好和更坏的范式。有经验的开发人员可以看到每个的优点,并为给定的问题选择最好的。
过程式编程并不是说你不能使用函数,函数式编程也不会阻止你使用类。这些范式只是帮助以一种随着代码增长而有益的方式来解决问题。
函数式编程vs面向对象编程vs过程式编程的JS演示比较DEV
发烧影音线怎么选?小白们需要关注的这些误区关于发烧线,音响系统中使用的主要有音频线,数字线,扬声器线及电源线。市场上的这些线材品种繁多,广告宣传更是让人眼花缭乱,不少线材更是被神话,使人对发烧线抱有太大的期望与幻想,其……
腾讯微保携手长城人寿推出新产品年年裕两全险1月12日,由腾讯微保、长城人寿共同举办的稳住我们能赢,裕见确定人生新品线上发布会圆满落幕。发布会上,腾讯微保副总裁尚教研携手长城人寿副总经理陈卓共同推出互联网专属两全产品新贵……
三元锂电池皇帝的新衣被比亚迪戳破困兽犹斗比亚迪汽车记者,漫画,纪录车这个时代需要一位战士来揭示新能源汽车的皇帝的新衣服。但没有人可以实现这首战士是比亚迪。近年来,中国和世界的新能源汽车是年度热门话语。与此同时,……
西圣XISEMOlafTWS耳机评测能打游戏能听音乐,效果还很多人喜欢听音乐,无论是早上起床刷牙,运动健身,出门旅游等都少不了听音乐。当然,用手机的外放喇叭直接听音乐的还是比较少,毕竟现在讲究的是个性化的娱乐,也就是需要的是私人的娱乐空……
汽车驾驶离自动尚远【光明时评】近日,一年轻企业家驾驶电动汽车时启用自动驾驶功能发生车祸离世,再度引发社会各界对自动驾驶技术的争论。虽然警方暂未公布具体结论,但最近几年间,全球范围内已发生了……
小红书或再次融资,商业化与用户体验仍是两难近期,国内种草社区赛道可谓是动作频频,前有陌陌推出树莓进军这一领域,后有消息称小红书将暂停在上市进程,也引发了外界的众多关注。在这其中,作为新人的树莓能否在激烈的市场竞争中占据……
这个售价6万续航4百的电动车如何?YOUNG光小新,听着有点俏皮劲儿,它是新特汽车刚推出的一款电动车,有S400和L400两款车型,官方指导价分别为5。98万元和6。58万元。从外形来看,YOUNG光小新……
苹果iOS系统被抵制,法国总统连夜更换手机,问题越来越大众所周知,任何手机的系统都不会是百分之百的安全,比如我们常用的:安卓、iOS等,它们之间的差距也就是谁的安全系数更高,谁的漏洞更大的问题。前不久一则丑闻更是让苹果系统陷入了舆论……
如何把同理心传给保安机器人和机器人保安以前说人与机器人的最大区别是人具有创造力,而机器人没有,但现在看来人工智能的创造力也不差。倒是活生生的人类越来越像机器人。比如越来越没有同情心,只会遵守秩序执行命令。即使是人命……
百度进军电视行业百度旗下人工智能助手小度官方宣布本月将推出两款新品,一款尺寸为2。98寸,另一款尺寸为86寸,本次产品发布也标志着百度正式进军电视行业。8月9日,百度旗下人工智能助手小度……
客观评价联想1,有人说想涉嫌贱卖国有资产,如果真的是这样,早就处理了,不会活到现在!国企改制是那时候的大潮,很多国企八九十年代效率低下,工人下岗,教训还不够深吗?所以国企改制是对的!股份制……
iOS14。8来了,即将发布苹果上个月分别推送了iOS14。7和iOS14。7。1正式版更新,加入了对新的MagSafe外接电池的支持,同时修复了此前系统存在的一些Bug。经过iAppleBytes……