JavaScript代码重构:何时以及如何不破坏项目

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

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

开始课程

你的代码能运行——但这并不意味着它很好

\n\n

你写了一个脚本。它能运行。客户很满意。但一个月过去了,你惊恐地看着那个已经膨胀到200行的函数。里面混杂着API请求、DOM操作和一些关于日期的魔法。熟悉吗?

\n\n

欢迎来到这样一个世界,在这里JavaScript代码重构不是完美主义者的任性,而是生存的必需。如果你希望你的项目能够长久存活,并且在第一次修改时不会崩溃,这篇文章就是为你准备的。

\n\n

什么是重构,什么不是

\n\n

我们从最重要的开始。JavaScript代码重构是在不改变程序外部行为的情况下改变其内部结构的过程。你并没有添加新功能,也没有修复bug。你只是让代码更干净、更易理解、更易于维护。

\n\n

很多人把重构和重写混为一谈。这是两回事。重写是指你扔掉旧代码,从头开始写新的。重构是进化,而不是革命。你通过小步骤改变代码,每次都检查是否有什么东西被破坏了。

\n\n

何时需要进行JavaScript重构?

\n\n

以下是几个明确的迹象,表明你的代码在呼救:

\n\n
    \n
  • 三次法则。如果你第三次复制同一段代码——是时候把它提取到一个单独的函数中了。
  • \n
  • 怪物函数。函数超过30-40行,无法一眼读完。
  • \n
  • “魔法数字”。代码中散布着像 86400000 或 42 这样的数字,没有注释和常量。
  • \n
  • 全局变量。如果你害怕修改一个变量,因为不知道它还在哪里被使用。
  • \n
  • 测试。如果你害怕进行修改,因为没有自动化测试——这是第一个警钟。
  • \n
\n\n

但也有不需要重构的情况:在截止日期前、在没有测试的生产环境中、或者代码是为明天就要丢弃的原型临时拼凑的。

\n\n

JavaScript重构技术:从简单到复杂

\n\n

1. 提取函数 (Extract Function)

\n\n

最流行且最安全的技术。你找到可以分组的代码片段,并将其提取到一个单独的函数中。

\n\n
// 重构前\nfunction calculateInvoice(items) {\n  let total = 0;\n  for (let item of items) {\n    total += item.price * item.quantity;\n  }\n  let discount = 0;\n  if (total > 1000) {\n    discount = total * 0.1;\n  }\n  return total - discount;\n}\n\n// 重构后\nfunction calculateSubtotal(items) {\n  return items.reduce((sum, item) => sum + item.price * item.quantity, 0);\n}\n\nfunction calculateDiscount(total) {\n  return total > 1000 ? total * 0.1 : 0;\n}\n\nfunction calculateInvoice(items) {\n  const subtotal = calculateSubtotal(items);\n  const discount = calculateDiscount(subtotal);\n  return subtotal - discount;\n}\n
\n\n

发生了什么变化?现在每个函数只负责一个动作。你可以在其他地方重用 calculateSubtotal,而 calculateDiscount 也很容易单独测试。

\n\n

2. 用常量替换魔法数字

\n\n

永远不要在代码中使用“裸”数字。一个月后,你自己都会不记得 86400000 是什么意思。

\n\n
// 不好\nif (Date.now() - lastLogin > 86400000) {\n  // 请求重新登录\n}\n\n// 好\nconst MILLISECONDS_IN_A_DAY = 24 * 60 * 60 * 1000;\nconst ONE_DAY_MS = 86400000; // 或者只是一个可读的常量\n\nif (Date.now() - lastLogin > ONE_DAY_MS) {\n  // 请求重新登录\n}\n
\n\n

3. 简化条件结构

\n\n

复杂的嵌套 if-else 是可读性的主要敌人。使用提前返回(early return)和三元运算符。

\n\n
<                

博客

书籍推荐