JavaScript 代码审查:真正让高级开发者恼火的是什么
\n\n每个开发者都至少收到过一个带有“这里最好重写”或“这是反模式”之类评论的拉取请求。如果您是初级或中级开发者,这样的意见常常看起来像是吹毛求疵。但高级开发者的每一句话背后都有真实的经验:生产环境中的故障、凌晨三点的错误或性能下降。
\n\n我们收集了高级开发者在 JavaScript 代码审查中最常留下的意见。这不仅仅是一个“这样不好,那样才好”的列表。这是对为什么特定方法被认为是糟糕的以及用什么来替代它的分析。
\n\n这篇文章对所有编写 JS 的人都有用:从新手到希望提升代码质量的经验丰富的开发者。
\n\n1. 输入数据突变:主要罪过
\n\n审查中最常见的错误之一——修改传递给函数的对象或数组。高级开发者讨厌这一点,因为突变破坏了不可变性并导致难以追踪的错误。
\n\n糟糕的例子
\nfunction addUser(users, newUser) {\n users.push(newUser); // 突变原始数组!\n return users;\n}\n\nconst allUsers = [{ id: 1 }, { id: 2 }];\nconst updated = addUser(allUsers, { id: 3 });\nconsole.log(allUsers.length); // 3 — 原始数组被修改了!\n\n正确做法
\nfunction addUser(users, newUser) {\n return [...users, newUser]; // 返回一个新数组\n}\n\nconst allUsers = [{ id: 1 }, { id: 2 }];\nconst updated = addUser(allUsers, { id: 3 });\nconsole.log(allUsers.length); // 2 — 原始数组未被触及\n\n为什么这很重要:当您突变输入数据时,任何引用同一对象的其他代码都会收到意外的更改。这是异步操作、Redux 存储和 React 状态中错误的直接途径。
\n\n2. 魔法数字和字符串:可读性的杀手
\n\n高级开发者经常在评论中写道:“数字 86400 是什么?”或“这个字符串从哪来的?”。魔法值使代码难以理解并增加了维护难度。
\n\n糟糕的例子
\nfunction calculateDiscount(price) {\n if (price > 1000) {\n return price * 0.9;\n }\n return price * 0.95;\n}\n\n正确做法
\nconst DISCOUNT_THRESHOLD = 1000;\nconst HIGH_DISCOUNT_RATE = 0.9;\nconst STANDARD_DISCOUNT_RATE = 0.95;\n\nfunction calculateDiscount(price) {\n if (price > DISCOUNT_THRESHOLD) {\n return price * HIGH_DISCOUNT_RATE;\n }\n return price * STANDARD_DISCOUNT_RATE;\n}\n\n建议:将所有常量提取到命名变量或单独的配置文件中。这简化了 JavaScript 代码审查并使其自文档化。
\n\n3. async/await 和 Promise 的错误
\n\n异步代码是即使是中级开发者也会犯错的地方。高级开发者在审查中关注两个主要方面:错误的错误处理和语法混用。
\n\n糟糕的例子(没有 catch 的 Promise)
\nasync function loadData() {\n const response = await fetch('/api/data');\n const data = await response.json();\n return data;\n}\n\n正确做法
\nasync function loadData() {\n try {\n const response = await fetch('/api/data');\n if (!response.ok) {\n throw new Error(`HTTP error! status: ${response.status}`);\n }\n const data = await response.json();\n return data;\n } catch (error) {\n console.error('数据加载错误:', error);\n throw error; // 如果需要,继续向上抛出\n }\n}\n\n重要:永远不要忽略错误。空的 catch 是邪恶的。如果发生了错误,您至少应该记录它,最好能正确处理它。
另一个常见错误——忘记 await
\nfunction processUsers(users) {\n users.forEach(async (user) => {\n await updateUser(user);