全国免费咨询:

13245491521

VR图标白色 VR图标黑色
X

中高端软件定制开发服务商

与我们取得联系

13245491521     13245491521

2024-09-25_现在前端组长都是这样做 Code Review

您的位置:首页 >> 新闻 >> 行业资讯

现在前端组长都是这样做 Code Review 点击关注公众号,“技术干货”及时达!前言 Code Review 是什么?Code Review 通常也简称 CR,中文意思就是 代码审查 一般来说 CR只关心代码规范和代码逻辑,不关心业务 但是,如果CR的人是组长,建议有时间还是看下与自己组内相关业务,能避免一些生产事故的发生 作为前端组长做 Code Review 有必要吗?主要还是看公司业务情况吧,如果前端组长需求不多的情况,是可以做下CR,能避免一些生产事故 锻炼自己的 CR 能力看看别人的代码哪方面写的更好,学习总结和同事交流,加深联系你做了 CR,晋升和面试,不就有东西吹了不是那要怎么去做Code Review呢?可以从几个方面入手 项目架构规范代码编写规范代码逻辑、代码优化业务需求具体要怎么做呢? 传统的做法是PR时查看,对于不合理的地方,打回并在PR中备注原因或优化方案 每隔一段时间,和组员开一个简短的CR分享会,把一些平时CR过程中遇到的问题做下总结 当然,不要直接指出是谁写出的代码有问题,毕竟这不是目的,分享会的目的是交流学习 人工CR需要很大的时间精力,与心智负担 随着 AI 的发展,我们可以借助一些 AI 来帮我们完成CR 接下来,我们来看下,vscode中是怎么借助 AI 工具来 CR 的 安装插件 CodeGeex 新建一个项目 mkdir code-reviewcd code-review创建 test.js 并用 vscode 打开 cd .test.jscode ./编写下 test.js function checkStatus() { if (isLogin()) { if (isVip()) { if (isDoubleCheck()) { done(); } else { throw new Error("不要重复点击"); } } else { throw new Error("不是会员"); } } else { throw new Error("未登录"); }}这是连续嵌套的判断逻辑,要怎么优化呢? 侧边栏选择这个 AI 插件,选择我们需要CR的代码 输入 codeRiview,回车 我们来看下 AI 给出的建议 AI 给出的建议还是很不错的,我们可以通过更多的提示词,优化它给出的修改建议,这里就不过多赘述了 通常我们优化这种类型的代码,基本优化思路也是,前置校验逻辑,正常逻辑后置 除了CodeGeex外,还有一些比较专业的 codeRiview 的 AI 工具 比如:CodeRabbit 那既然都有 AI 工具了,我们还需要自己去CR 吗? 还是有必要的,借助 AI 工具我们可以减少一些阅读大量代码环节,提高效率,减少 CR 的时间 但是仍然需要我们根据 AI 工具的建议进行改进,并且总结,有利于拓宽我们见识,从而写出更优质的代码 具体 CR 实践 判断逻辑优化1. 深层对象判空 // 深层对象if ( store.getters && store.getters.userInfo && store.getters.userInfo.menus) {}// 可以使用 可选链进行优化if (store?.getters?.userInfo?.menus) {}2. 空函数判断 优化之前 props.onChange && props.onChange(e)支持 ES11 可选链写法,可这样优化,js 中需要这样,ts 因为有属性校验,可以不需要判断,当然也特殊情况 props?.onChange?.(e)老项目,不支持 ES11 可以这样写 const NOOP = () = 8const { onChange = NOOP } = propsonChange(e)3. 复杂判断逻辑抽离成单独函数 // 复杂判断逻辑function checkGameStatus() { if (remaining === 0 || (remaining === 1 && remainingPlayers === 1) || remainingPlayers === 0) { quitGame() }}// 复杂判断逻辑抽离成单独函数,更方便阅读function isGameOver() { return ( remaining === 0 || (remaining === 1 && remainingPlayers === 1) || remainingPlayers === 0 );} function checkGameStatus() { if (isGameOver()) { quitGame(); }}4. 判断处理逻辑正确的梳理方式 // 判断逻辑不要嵌套太深function checkStatus() { if (isLogin()) { if (isVip()) { if (isDoubleCheck()) { done(); } else { throw new Error('不要重复点击'); } } else { throw new Error('不是会员'); } } else { throw new Error('未登录'); }}这个是不是很熟悉呀~ 没错,这就是使用 AI 工具 CR的代码片段 通常这种,为了处理特殊状况,所实现的判断逻辑,都可以采用 “异常逻辑前置,正常逻辑后置” 的方式进行梳理优化 // 将判断逻辑的异常逻辑提前,将正常逻辑后置function checkStatus() { if (!isLogin()) { throw new Error('未登录'); } if (!isVip()) { throw new Error('不是会员'); } if (!isDoubleCheck()) { throw new Error('不要重复点击'); } done();}函数传参优化// 形参有非常多个const getMyInfo = ( name, age, gender, address, phone, email,) = { // ...}有时,形参有非常多个,这会造成什么问题呢? 传实参是的时候,不仅需要知道传入参数的个数,还得知道传入顺序有些参数非必传,还要注意添加默认值,且编写的时候只能从形参的后面添加,很不方便所以啊,那么多的形参,会有很大的心智负担怎么优化呢? // 行参封装成对象,对象函数内部解构const getMyInfo = (options) = { const { name, age, gender, address, phone, email } = options; // ...} getMyInfo( { name: '张三', age: 18, gender: '男', address: '北京', phone: '123456789', email: '123456789@qq.com' })你看这样是不是就清爽了很多了 命名注释优化1. 避免魔法数字 // 魔法数字if (state === 1 || state === 2) { // ...} else if (state === 3) { // ...}咋一看,这 1、2、3 又是什么意思啊?这是判断啥的? 语义就很不明确,当然,你也可以在旁边写注释 更优雅的做法是,将魔法数字改用常量 这样,其他人一看到常量名大概就知道,判断的是啥了 // 魔法数字改用常量const UNPUBLISHED = 1;const PUBLISHED = 2;const DELETED = 3; if (state === UNPUBLISHED || state === PUBLISHED) { // ...} else if (state === DELETED) { // ...}2. 注释别写只表面意思 注释的作用:提供代码没有提供的额外信息 // 无效注释let id = 1 // id 赋值为 1 // 有效注释,写业务逻辑 what & whylet id = 1 // 赋值文章 id 为 13. 合理利用命名空间缩短属性前缀 // 过长命名前缀class User { userName; userAge; userPwd; userLogin() { }; userRegister() { };}如果我们把前面的类里面,变量名、函数名前面的 user 去掉 似乎,也一样能理解变量和函数名称所代表的意思 代码却,清爽了不少 // 利用命名空间缩短属性前缀class User { name; age; pwd; login() {}; register() {};}分支逻辑优化什么是分支逻辑呢? 使用 if else、switch case ...,这些都是分支逻辑 // switch caseconst statusMap = (status: string) = { switch(status) { case 'success': return 'SuccessFully' case 'fail': return 'failed' case 'danger' return 'dangerous' case 'info' return 'information' case 'text' return 'texts' default: return status }}// if elseconst statusMap = (status: string) = { if(status === 'success') return 'SuccessFully' else if (status === 'fail') return 'failed' else if (status === 'danger') return 'dangerous' else if (status === 'info') return 'information' else if (status === 'text') return 'texts' else return status}这些处理逻辑,我们可以采用 映射代替分支逻辑 // 使用映射进行优化const STATUS_MAP = { 'success': 'Successfull', 'fail': 'failed', 'warn': 'warning', 'danger': 'dangerous', 'info': 'information', 'text': 'texts'} return STATUS_MAP[status] ?? status【扩展】 ?? 是 TypeScript 中的 “空值合并操作符” 当前面的值为 null 或者 undefined 时,取后面的值 对象赋值优化// 多个对像属性赋值const setStyle = () = { content.body.head_style.style.color = 'red' content.body.head_style.style.background = 'yellow' content.body.head_style.style.width = '100px' content.body.head_style.style.height = '300px' // ...}这样一个个赋值太麻烦了,全部放一起赋值不就行了 可能,有些同学就这样写 const setStyle = () = { content.body.head_style.style = { color: 'red', background: 'yellow', width: '100px', height: '300px' }}咋一看,好像没问题了呀?那 style 要是有其他属性呢,其他属性不就直接没了吗~ const setStyle = () = { content.body.head_style.style = { ...content.body.head_style.style color: 'red', background: 'yellow', width: '100px', height: '300px' }}采用展开运算符,将原属性插入,然后从后面覆盖新属性,这样原属性就不会丢了 隐式耦合优化// 隐式耦合function responseInterceptor(response) { const token = response.headers.get("authorization"); if (token) { localStorage.setItem('token', token); }} function requestInterceptor(response) { const token = localStorage.getItem('token'); if (token) { response.headers.set("authorization", token); }}这个上面两个函数有耦合的地方,但是不太明显 比如这样的情况,有一天,我不想在 responseInterceptor 函数中保存 token 到 localStorage了 function responseInterceptor(response) { const token = response.headers.get("authorization");} function requestInterceptor(response) { const token = localStorage.getItem('token'); if (token) { response.headers.set("authorization", token); }}会发生什么? localStorage.getItem('token')一直拿不到数据,requestInterceptor 这个函数就报废了,没用了 函数 responseInterceptor改动,影响到函数 requestInterceptor 了,隐式耦合了 怎么优化呢? // 将隐式耦合的常数抽离成常量const TOKEN_KEY = "authorization";const TOKEN = 'token'; function responseInterceptor(response) { const token = response.headers.get(TOKEN_KEY); if (token) { localStorage.setItem(TOKEN_KEY, token); }} function requestInterceptor(response) { const token = localStorage.getItem(TOKEN_KEY); if (token) { response.headers.set(TOKEN_KEY, token); }}这样做有什么好处呢?比刚才好在哪里? 还是刚才的例子,我去掉了保存 localStorage.setItem(TOKEN_KEY, token) 我可以根据TOKEN_KEY这个常量来查找还有哪些地方用到了这个 TOKEN_KEY,从而进行修改,就不会出现冗余,或错误 不对啊,那我不用常量,用token也可以查找啊,但你想想 token 这个词是不是得全局查找,其他地方也会出现token 查找起来比较费时间,有时可能还会改错了 用常量的话,全局查找出现重复的概率很小 而且如果你是用 ts 的话,window 下鼠标停在常量上,按 ALT 键就能看到使用到这个常量的地方了,非常方便 小结 codeRiview(代码审查)不仅对个人技能的成长有帮助,也对我们在升职加薪、面试有所裨益 CR 除了传统的方式外,也可以借助 AI 工具,来简化其中流程,提高效率 上述的优化案例,虽然优化方式不同,但是核心思想都是一样,都是为了代码 更简洁、更容易理解、更容易维护 当然了,优化方式还有很多,如果后期遇到了也会继续补充进来 点击关注公众号,“技术干货”及时达! 阅读原文

上一篇:2024-03-17_首个AI软件工程师Devin完整技术报告出炉,还有人用GPT做出了「复刻版」 下一篇:2025-07-27_鳍源x索尼水下机器人拍摄解决方案,引领影视产业水下拍摄发展

TAG标签:

17
网站开发网络凭借多年的网站建设经验,坚持以“帮助中小企业实现网络营销化”为宗旨,累计为4000多家客户提供品质建站服务,得到了客户的一致好评。如果您有网站建设网站改版域名注册主机空间手机网站建设网站备案等方面的需求...
请立即点击咨询我们或拨打咨询热线:13245491521 13245491521 ,我们会详细为你一一解答你心中的疑难。
项目经理在线

相关阅读 更多>>

猜您喜欢更多>>

我们已经准备好了,你呢?
2022我们与您携手共赢,为您的企业营销保驾护航!

不达标就退款

高性价比建站

免费网站代备案

1对1原创设计服务

7×24小时售后支持

 

全国免费咨询:

13245491521

业务咨询:13245491521 / 13245491521

节假值班:13245491521()

联系地址:

Copyright © 2019-2025      ICP备案:沪ICP备19027192号-6 法律顾问:律师XXX支持

在线
客服

技术在线服务时间:9:00-20:00

在网站开发,您对接的直接是技术员,而非客服传话!

电话
咨询

13245491521
7*24小时客服热线

13245491521
项目经理手机

微信
咨询

加微信获取报价