编程入门·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 - 永远不要用
data、info、temp、obj、arr这种"说了等于没说"的名字
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 个问题:
- 输入是
null/undefined怎么办? - 输入是空数组 / 空字符串怎么办?
- 输入是负数 / 0 怎么办?
- 输入是错误类型(字符串当数字传)怎么办?
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 也减少了。这就是「干净代码」的力量。
最后
写出干净代码不是天赋,是习惯。每写一段代码,问自己:
「三个月后的我,看到这段代码,会想揍现在的自己吗?」
如果答案是肯定的,就花两分钟改一改。这两分钟,能为未来的你省下两小时。
「治大国若烹小鲜。」 写代码亦然 —— 慢一点,稳一点,每个细节都重要。