</>小白学编程.dev
编程入门·6 分钟阅读·作者:小白学编程

写出别人愿意读的代码:小白的 10 条「干净代码」准则

代码不仅仅是写给机器的,更是写给人的。这 10 条准则会让你的代码立刻看起来像「老手」写的。

一句话总结

代码被读的次数 ≫ 被写的次数。

新手最容易忽视的事实:你写的代码,未来一定会被人读到(包括你自己)。每一行写得"将就"的代码,都会变成未来某天的"债务"。

下面 10 条准则按照"性价比"排序:第一条改了,效果比后九条加起来还大

1. 起一个会说话的名字

// ❌ 这是什么?
const d = 7 * 24 * 60 * 60 * 1000;
const arr = users.filter(x => x.t > d);

// ✅ 一目了然
const ONE_WEEK_MS = 7 * 24 * 60 * 60 * 1000;
const recentUsers = users.filter(user => user.lastActiveAt > ONE_WEEK_MS);

口诀

  • 变量、函数 → 用名词 / 动词短语
  • 布尔值 → 用 is / has / can 开头
  • 常量 → UPPER_SNAKE_CASE
  • 永远不要用 datainfotempobjarr 这种"说了等于没说"的名字

2. 一个函数只做一件事

// ❌ 这函数到底叫"加载用户"还是"渲染头像"?
function loadUser(id) {
  const user = fetchUser(id);
  document.getElementById("avatar").src = user.avatar;
  return user;
}

// ✅ 各司其职
function loadUser(id) { return fetchUser(id); }
function renderAvatar(user) { document.getElementById("avatar").src = user.avatar; }

老子曰:"曲则全。"——把大函数拆细,反而能让整体更完整。

3. 控制嵌套深度

嵌套超过 3 层的代码,几乎无法阅读:

// ❌ 嵌套地狱
function process(user) {
  if (user) {
    if (user.isActive) {
      if (user.role === "admin") {
        // ... 真正的逻辑在这里
      }
    }
  }
}

// ✅ 提前 return(卫语句)
function process(user) {
  if (!user) return;
  if (!user.isActive) return;
  if (user.role !== "admin") return;
  // ... 真正的逻辑
}

4. 不要写"魔法数字"

// ❌ 8 是什么?1024 是什么?
if (password.length < 8) throw new Error("...");
if (file.size > 1024 * 1024 * 5) throw new Error("...");

// ✅ 命名常量讲清楚意图
const MIN_PASSWORD_LENGTH = 8;
const MAX_FILE_SIZE_MB = 5;

if (password.length < MIN_PASSWORD_LENGTH) throw new Error("...");
if (file.size > MAX_FILE_SIZE_MB * 1024 * 1024) throw new Error("...");

5. 注释解释「为什么」,不解释「是什么」

// ❌ 废话注释
i = i + 1;  // 把 i 加 1

// ✅ 解释意图
// 跳过表头行(CSV 文件的第一行是字段名)
i = i + 1;

好的代码本身就是注释。能用更好的命名解决的,就别写注释。

6. 不要重复自己(DRY 原则)

// ❌
const isWeekend1 = day === "Sat" || day === "Sun";
// ...50 行后……
const isWeekend2 = today === "Sat" || today === "Sun";

// ✅
const WEEKEND = ["Sat", "Sun"];
const isWeekend = (day) => WEEKEND.includes(day);

但也别过度抽象 —— 当你发现 3 处重复时再考虑提取,别看见 2 处就动手。

7. 处理边界情况

新手代码"跑通"和老手代码"健壮"的差别,往往就在边界:

function average(nums) {
  // 边界:空数组、null、undefined、不是数组
  if (!Array.isArray(nums) || nums.length === 0) return 0;
  return nums.reduce((s, n) => s + n, 0) / nums.length;
}

练习:你写下的每个函数,问自己 4 个问题:

  1. 输入是 null / undefined 怎么办?
  2. 输入是空数组 / 空字符串怎么办?
  3. 输入是负数 / 0 怎么办?
  4. 输入是错误类型(字符串当数字传)怎么办?

8. 别在条件里藏副作用

// ❌ 在 if 里偷偷调用 + 修改了 user
if ((user = fetchCurrentUser()) && user.isActive) {
  // ...
}

// ✅ 一目了然
const user = fetchCurrentUser();
if (user && user.isActive) {
  // ...
}

9. 每个函数控制在「一个屏幕」内

具体多少行不重要,核心标准是:别人不需要滚动屏幕也能看完它的全部逻辑

如果超过了,多半是因为它不止做"一件事"(回到 #2)。

10. 用工具自动化

把"风格"这件事,交给工具,不要靠"自觉":

# JavaScript / TypeScript
npm install -D prettier eslint
// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "trailingComma": "all",
  "printWidth": 100
}

配合 VSCode 设置"保存时自动格式化",从此你永远不用再为缩进、引号、分号操心

一个综合示例

把上面 10 条用到一起:

// ❌ 之前
function p(d){
  let r = []
  for (let i = 0; i < d.length; i++) {
    if (d[i].s == 1) {
      if (d[i].a > 18) {
        r.push({n: d[i].n, a: d[i].a})
      }
    }
  }
  return r
}

// ✅ 之后
const STATUS_ACTIVE = 1;
const ADULT_AGE = 18;

function getActiveAdults(users) {
  if (!Array.isArray(users)) return [];
  return users
    .filter((u) => u.status === STATUS_ACTIVE && u.age > ADULT_AGE)
    .map(({ name, age }) => ({ name, age }));
}

代码量减少了,可读性提升了,bug 也减少了。这就是「干净代码」的力量

最后

写出干净代码不是天赋,是习惯。每写一段代码,问自己:

「三个月后的我,看到这段代码,会想揍现在的自己吗?」

如果答案是肯定的,就花两分钟改一改。这两分钟,能为未来的你省下两小时

「治大国若烹小鲜。」 写代码亦然 —— 慢一点,稳一点,每个细节都重要。

📖 相关阅读