先说下我的巅峰之作,是二月份给后台管理系统写的一个筛选区联动。多选框选完一级,二级要根据一级的选中项重新过滤,需求本身没什么,但我当时赶着发版,写完之后连我自己都要看五分钟才敢动。大概是这个路子:两层 for 嵌套加一个 forEach,里面还夹着 for (let i = 0; i < arr.length; i++) { if (arr[i+1]?.xxx === yyy) { flag = true; } }。当时我确实知道 arr[i+1] 可能越界,就加了个可选链 ?.,然后理直气壮地写了个 flag 变量,循环完了才 return flag。就这种写法,见一次想把当时的自己掐死一次。
前天组里做代码 review,我们组长皱了半天眉,说了句“这段真像你写的”。晚上回家我越想越气,就把那坨代码贴给 AI 了,让它帮我重写。当时是这么喂的:“帮我看下这段,多选取消之后二级列表不刷新,有时候还会报错。”
AI 给了一版新的,用了 Set 和 filter,干净得像别人的代码。但我看了半天觉得哪里不对。查了下,它把 selectedIds 的默认值直接改成了一个空数组 [],但原来的需求是“不选时默认包含全部”。我说它不是帮我修 bug,它直接改需求了。我又让它按原先的语义重写,它回了句“这允许你保持原来的默认行为”,好吧,这句倒是对的。
然后真正的翻车来了。AI 重写的版本用了一个 Map 来存选中项的临时状态,接口那边不认这个结构,请求直接 400。我一开始以为是接口的 key 写错了,对着控制台的 payload 看了半天,发现它把 selectedIds 从数组变成了对象。那时候我想骂人,但想想是我自己没交代清楚。最后我自己动手,把它生成的 Map 拆回数组再提交。
改完之后一跑——通了。整个流程丝滑起来了,二级列表刷新正常,取消选中也正常,报错也没了。那一刻真的爽。但心底又有点不舒服,我那版虽然烂,至少接口结构是对的,AI 看起来优雅,反而跑了两次才跑通。
不过说真的,AI 重写完之后我再回去看我原来的代码,发现有一处我依赖的怪逻辑其实可以直接删掉。就是“取消选中的时候要手动把二级列表清空”,AI 没找我这条逻辑,因为它的写法不需要清空。这说明它可以跑通不是靠运气,是真懂了。我做不到它那么熟练,但至少现在知道啥样的代码不丢人。
今日单词:refactor,重构。我查了第四遍了,还是记不住拼写。