点击一键订阅《云荐大咖》专栏,获取官方推荐优质内容,学技术不迷路!可读的代码可以大大提高开发效率。在开发过程中,有很大一部分时间花在阅读代码上。可读代码易于理解和更改。相反,不可读的代码使其难以阅读并且容易出错修改。这是一段不可读的代码:constuser=...constfoo=(cb)=>...constbar=(list,cb)=>...constother=(list1,list2)=>。..if(user?user.isAdmin:((user.permission&&user.permission.view)?user.permission.view===true:false)){foo((res)=>{if(res&&res.ok&&res.list&&res.list.length>0){bar(res.list,(res2)=>{if(res2&&res2.ok&&res2.list&&res2.list.length>0){其他(res.list,res2.list)}})}})}上面的代码有这些问题:函数的命名与函数不匹配。if条件太复杂且嵌套太深。回调函数嵌套很深。将上面的代码改成可读的代码:constuser=...constfetchChannel=()=>...constfetchArticle=(list)=>...constrender=(channelList,articleList)=>...consthasViewPermission=user.isAdmin||user.permission?.viewif(!hasViewPermission){return}const{ok,list:channelList}=awaitfetchChannel()if(!(ok&&channelList?.length>0)){return}const{ok:fetchArticleOk,articleList}=awaitfetchArticle(channelList)if(!(fetchArticleOk&&articleList.length>0)){return}render(channelList,articleList)综上所述,可读代码主要有如下特点:代码风格一致。合理命名。必要的意见。没有大文件。没有深度嵌套的代码。如何编写可读代码?要编写可读代码,必须满足上述特征。1.一致的代码风格一致的代码风格是指:空格、缩进、命名风格(驼峰、破折号等)在整个项目中保持一致。一致的代码风格看起来很整洁,降低了理解成本。在一个项目中,使用什么编码风格并不重要。风格一致很重要。前端行业比较知名的代码风格有:AirbnbJavaScriptStyleGuide和JavaScriptStandardStyle。如果你不想乱来,你可以使用JavaScriptStandardStyle。JavaScript标准风格的特点:无需配置。史上最便捷的统一代码风格,轻松拥有。自动代码格式化。只需运行标准--fix并告别混乱的代码。尽早发现文体和程序问题。减少代码审查过程中的迭代修改过程,节省时间。确定代码风格后,可以使用检测工具ESLint来保证代码风格的统一性。每次提交代码前,做一个检查,可以使用工具:husky。对于大型项目,检查整个项目太慢了。使用lint-staged仅检查更改的文件。2.合理命名计算机科学中只有两件难事:缓存失效和命名事物。计算机科学中只有两件难事:缓存失效和命名事物。——菲尔·卡尔顿好的命名是“知其名”。具体来说,好的命名具有以下特点:直截了当、意味深长。一个好的命名是通俗易懂的,即直截了当、意味深长。例如:获取用户信息。建议:故宫命名法提取目标对象的关键特征进行命名。推荐命名工具:CODELF。它可以帮助您在Github和GitLab等网站中搜索您想要查找的不同名称的内容。小心不要拼错名称中的单词。推荐单词拼写检查工具:CodeSpellChecker。遵循行业惯例好的命名也应该遵循行业惯例。例如:行业惯例id作为唯一标识符来命名,不要使用identifier。i、j、k用于命名循环计数变量。好的命名应该符合当前项目的代码风格。如:驼峰风格等不好的命名有以下特点:无意义的名字,如:foo、bar、var1、fun1。过于抽象的名称过于抽象的名称,如:data、res、temp、tools。会有歧义的缩写会有歧义的缩写,比如:mod。您可能无法确定它是模式还是模块。不必要的上下文信息//badfunctionasyncgetUserName(userId){constuserName=awaitfetchUser(userId)returnuserName}//goodfunctionasyncgetUserName(id){constname=awaitfetchUser(id)returnname}toolongnametooLongname,不容易理解。如:fetchGraintYoungestBoyName。优化方法:省略不重要的内容。比如改为:fetchBoyName。3.必要的注释注释是对代码的解释和说明。好的代码是不言自明的。对于不复杂的代码,不需要注释。如果写的注释只是说明代码做了什么,不仅会浪费读者的时间,还会误导读者(当注释和代码的功能不一致时)。需要写注释的场景:当代码本身不能清楚说明作者的意图时。逻辑比较复杂。4.没有大文件。大文件是指代码行数很多(1000行以上)的文件。大文件意味着代码会做很多事情,而且很难跟踪正在发生的事情。可以使用ESLine中的最大行数规则找到大文件。优化方案:将大文件按功能拆分成若干个小文件。5.没有深度嵌套的代码。深度嵌套的代码可读性差,让人产生“敬畏”之感。例如:fetchData1(data1=>fetchData2(data2=>fetchData3(data3=>fetchData4(data4=>fetchData5(data5=>fetchData6(data6=>fetchData7(data7=>done(data1,data2,data3,dat4,data5,data6,data7))))))))))以下是一些常见的深层嵌套场景。1.回调地狱使用回调函数处理多个串行异步操作会造成深度嵌套。俗称“回调地狱”。如:fetchData1(data1=>fetchData2(data2=>fetchData3(data3=>done(data1,data2,data3))))2.如果嵌套很深在条件语句中,如果判断条件很多,嵌套会verydeep条件很深或者判断条件很长的情况。比如判断一个值是否是:1到100之间,能被3和5整除的偶数。像这样写:constisEvenNum=num=>Number.isInteger(num)&&num%2===0constisBetween=num=>num>1&&num<100constisDivisible=num=>num%3===0&&num%5===0if(isEvenNum(num)){//是偶数if(isBetween(num)){//在1和100之间if(isDivisible(num)){//可以被3和5整除returntrue}returnfalse}returnfalse}returnfalse三元表达式也可以深度嵌套:a>0?(b<5>?(c?d:e):(f?g:h)):(i?j:k)3、函数调用嵌套执行多个函数调用,每个函数的输出为下一个函数的输入,会造成深度嵌套。例如://模拟炒鸡蛋的过程:买鸡蛋->打鸡蛋->炒鸡蛋->上桌。toTable(//Step4:上桌fry(//Step3:炒鸡蛋handle(//Step2:Beateggsbuy(20)//Step1:Buyeggs)))4.React高级组件嵌套在用React编写的应用程序中,一个组件可能被许多高阶组件(HOC)包裹,从而导致深度嵌套。如:classCompextendsReact.Component{...}Wrapper5(Wrapper4(Wrapper3(Wrapper2(Wrapper1(Comp)))))5.ReactContext嵌套在React编写的应用中,可以使用Context来管理子组件数据共享。如果共享数据很多,类型不一,很容易造成顶层组件Context嵌套很深。如:
