JavaScript 代码审查:检查什么才能让代码不崩溃
\n\n你是否曾经打开过别人的 pull request,感觉内心一阵紧缩?就像看着一团乱麻,每个节点都是一个潜在的 Bug。JavaScript 代码审查不仅仅是任务追踪器上的一个勾选标记。它是你抵御混乱的最后一道防线。尤其是在动态的 JS 世界中,类型只是幻觉,“魔法般”的行为才是常态。
\n\n在这篇文章中,我将告诉你审查 JavaScript 代码时真正需要关注什么。忘掉那些关于制表符 vs 空格的毫无意义的争论。我们将讨论直接影响稳定性、可读性和性能的事情。这就是我本人使用的那个代码审查清单。
\n\n1. 函数的纯净性与无副作用
\n\n第一点,也是最重要的一点。一个函数应该只做一件事,并且把它做好。如果你看到一个函数同时在做数据验证、发送服务器请求和更新全局状态——这就是一个危险信号。
\n\n检查什么:
\n- \n
- 参数数量:理想情况是 0,最多不超过 3 个。如果更多,请将其提取到一个配置对象中。 \n
- 输入数据的突变:函数不应修改传入的数组或对象。这是一个难以捕获的硬核 Bug。 \n
- 副作用:任何对外部世界的改变(console.log、写入文件、修改 DOM)都应该是明确且合理的。 \n
糟糕示例:
\nlet totalUsers = 0;\n\nfunction processUsers(users) {\n for (let i = 0; i < users.length; i++) {\n users[i].active = true; // 输入数据突变!\n totalUsers++; // 副作用!\n console.log(users[i]); // 又一个副作用\n }\n return users;\n}\n\n优秀示例:
\nfunction activateUsers(users) {\n return users.map(user => ({ ...user, active: true }));\n}\n\n// 使用:\nconst activeUsers = activateUsers(users);\nconsole.log(`已激活:${activeUsers.length}`);\n\n请记住:纯函数是可预测代码的基础。如果在代码审查中看到数据突变——请毫不犹豫地写下评论。这是 JavaScript 中难以捉摸的 Bug 的主要原因之一。
\n\n2. 异步:Promise 和 async/await
\n\nJS 是异步之王,但同时也是回调地狱之王。审查时请注意异步操作的处理方式。不分析 Promise 链的JavaScript 代码检查就是走过场。
\n\n危险信号:
\n- \n
- 缺少错误处理:没有
.catch()或try/catch。迟早会导致应用程序崩溃。 \n - 嵌套的 Promise:如果你看到
.then()里面还有.then()——这就是重构的理由。 \n - 忘记使用
await:函数被标记为async,但内部调用没有await。结果将是 undefined 而不是数据。 \n
糟糕示例(缺少错误处理):
\nasync function fetchUserData(userId) {\n const response = await fetch(`/api/users/${userId}`);\n const data = await response.json();\n return data;\n}\n\n优秀示例:
\nasync function fetchUserData(userId) {\n try {\n const response = await fetch(`/api/users/${userId}`);\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n return await response.json();\n } catch (error) {\n console.error('加载用户时出错:', error);\n throw error; // 继续抛出,但记录日志\n }\n}\n\n给审查者的建议:始终要求解释为什么没有使用 try/c