JavaScript 代码审查:检查什么才能让代码不崩溃

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

JavaScript 代码审查:检查什么才能让代码不崩溃

\n\n

你是否曾经打开过别人的 pull request,感觉内心一阵紧缩?就像看着一团乱麻,每个节点都是一个潜在的 Bug。JavaScript 代码审查不仅仅是任务追踪器上的一个勾选标记。它是你抵御混乱的最后一道防线。尤其是在动态的 JS 世界中,类型只是幻觉,“魔法般”的行为才是常态。

\n\n

在这篇文章中,我将告诉你审查 JavaScript 代码时真正需要关注什么。忘掉那些关于制表符 vs 空格的毫无意义的争论。我们将讨论直接影响稳定性、可读性和性能的事情。这就是我本人使用的那个代码审查清单。

\n\n

1. 函数的纯净性与无副作用

\n\n

第一点,也是最重要的一点。一个函数应该只做一件事,并且把它做好。如果你看到一个函数同时在做数据验证、发送服务器请求和更新全局状态——这就是一个危险信号。

\n\n

检查什么:

\n
    \n
  • 参数数量:理想情况是 0,最多不超过 3 个。如果更多,请将其提取到一个配置对象中。
  • \n
  • 输入数据的突变:函数不应修改传入的数组或对象。这是一个难以捕获的硬核 Bug。
  • \n
  • 副作用:任何对外部世界的改变(console.log、写入文件、修改 DOM)都应该是明确且合理的。
  • \n
\n\n

糟糕示例:

\n
let 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

优秀示例:

\n
function 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\n

2. 异步:Promise 和 async/await

\n\n

JS 是异步之王,但同时也是回调地狱之王。审查时请注意异步操作的处理方式。不分析 Promise 链的JavaScript 代码检查就是走过场。

\n\n

危险信号:

\n
    \n
  • 缺少错误处理:没有 .catch() 或 try/catch。迟早会导致应用程序崩溃。
  • \n
  • 嵌套的 Promise:如果你看到 .then() 里面还有 .then()——这就是重构的理由。
  • \n
  • 忘记使用 await:函数被标记为 async,但内部调用没有 await。结果将是 undefined 而不是数据。
  • \n
\n\n

糟糕示例(缺少错误处理):

\n
async function fetchUserData(userId) {\n    const response = await fetch(`/api/users/${userId}`);\n    const data = await response.json();\n    return data;\n}
\n\n

优秀示例:

\n
async 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

博客

书籍推荐