写给自学前端同学的编程法则
这些原则不是什么高深的理论,都是前人踩坑总结出来的经验。其实好的代码就像好的文章:结构清晰:每个部分都有明确的作用语言简洁:用最简单的词表达清楚的意思逻辑流畅:读起来一气呵成,不用来回翻页易于理解:即使是外行人也能明白在说什么记住这些原则,哪怕是 AI 生成的代码,也可以让它有质的飞跃!
你可能想:“现在都是 AI 写代码了,有必要学这个吗?”
确实,AI 确实很强大,但它有 2 个致命的局限:
1. AI 生成的代码质量参差不齐
AI 是根据概率生成代码的,它并不知道什么是“好的代码”。如果你不告诉它,它可能会给你生成一个把所有逻辑都塞在一起的千行函数——看似能跑,实则维护噩梦。
2. 和 AI 对话需要清晰的思路
想让 AI 帮你写出好代码,你首先得知道“好代码”长什么样。
这些编程原则就是你和 AI 沟通的“语言”:
-
你可以告诉 AI:“帮我拆分成单一职责的函数”
-
你可以问 AI:“这段代码的抽象层次是否一致?”
-
你可以要求 AI:“请用幂等的方式重写这段逻辑”
不懂原则,你就无法判断 AI 给的东西好不好,更没法指导 AI 改进。
AI 改变了写代码的方式,但没有改变好代码的标准。
以前,你手写代码,考验的是打字速度和语法记忆。现在,你和 AI 协作,考验的是:
-
代码审查能力: 一眼看出 AI 生成的代码有没有问题
-
架构设计能力: 告诉 AI 应该怎么组织代码结构
-
问题解决能力: 当 AI 搞不定时,从更高层次思考
这些能力的基础,就是我今天要分享的这些编程原则。
1. 法则一:三次法则
很多新手有个通病:一上来就想写出“完美”的代码。
-
“这个函数将来可能需要什么功能?”
-
“这个功能是不是应该做成通用的?”
-
“这里的代码还能不能优化?”
结果呢?代码越写越复杂,时间越花越多,最后反而写不出好用的代码。
说句大实话:先让它跑起来,再说别的。
由此诞生了三次法则。具体怎么做:
-
第一次写:直接写,不要想太多。代码能实现功能就行,重复就重复。
-
第二次写:发现又要写同样的代码?直接复制粘贴,稍作修改就完事。
-
第三次写:这时候才需要思考,能不能把这些重复代码整合成一个通用的函数?
为什么要这样呢?
因为只有写了三遍,你才能真正明白:
-
这些代码的真正需求是什么?
-
哪些部分是真正通用的?
-
怎么抽象才最合适?
简单说,就是别想太多,先写起来再说。
2. 法则二:三步走
写代码要遵循这个步骤:
第一步:让它能跑(Make it work)
别管代码多丑,先让功能正常运行;别担心性能问题,先确保逻辑正确;别想架构问题,先把基本功能实现。
第二步:让它正确(Make it right)
补充测试用例,确保各种边缘情况都能处理。
第三步:让它快速(Make it fast)
进行性能优化。
很多时候,你会发现根本走不到第三步。 因为大部分场景下,“够用”就行了。
3. 法则三:每个函数只做一件事
好的函数就像好的工具:专一、高效、易用。
一个函数应该只负责一件事,就像螺丝刀只负责拧螺丝,锤子只负责敲钉子。
比如这样一段代码:
// 这样的函数做太多事情了
async function processUser() {
// 1. 从数据库获取用户数据
const users = await database.fetchAllUsers();
// 2. 筛选活跃用户
const activeUsers = users.filter(user => user.isActive);
// 3. 给活跃用户发邮件
activeUsers.forEach(user => {
sendEmail(user.email, "Hello active user!");
});
// 4. 统计活跃用户数量
const count = activeUsers.length;
// 5. 记录日志
console.log(`处理了 ${count} 个活跃用户`);
}
一个函数做了 5 件不同的事情:获取数据、筛选、发邮件、统计、记录日志。
其实应该拆成:
// 拆分成多个专一的函数
async function getActiveUsers() {
const users = await database.fetchAllUsers();
return users.filter(user => user.isActive);
}
function sendEmailsToUsers(users) {
users.forEach(user => {
sendEmail(user.email, "Hello active user!");
});
}
function logUserCount(count) {
console.log(`处理了 ${count} 个活跃用户`);
}
// 主要流程函数,只负责协调
async function processUsers() {
const activeUsers = await getActiveUsers();
sendEmailsToUsers(activeUsers);
logUserCount(activeUsers.length);
}
使用这种方式:
-
容易理解:每个函数做的事情一目了然
-
容易测试:单独测试每个功能
-
容易修改:想改发邮件逻辑,不用动获取数据的代码
-
容易复用:获取活跃用户的逻辑其他地方也能用
4. 法则四:幂等性
听起来很专业,其实很简单:同样的输入,每次都得到同样的输出。
举个例子:
// 不幂等的写法
let count = 0;
function increment() {
count = count + 1; // 每次调用结果都不一样
}
// 幂等的写法
function setCount(value) {
count = value; // 不管调用多少次,传同样的值结果都一样
}
之所以要这样做,是因为在真实的开发场景里,很多操作可能会被重复执行:
-
用户手抖点了两次提交按钮
-
网络不好,请求重试了
-
定时任务因为某些原因跑了两遍
如果你的代码不是幂等的,这些情况都可能出问题。
5. 法则五:保持一个抽象层次
简单说就是:同一个函数里,代码的“颗粒度”要保持一致。
举个例子:
// 不好的写法 - 抽象层次混乱
function processUser(userId) {
const user = getUser(userId);
// 突然开始写具体的实现细节
if (user.age > 18 && user.status === 'active' && !user.banned) {
// 又回到高层抽象
sendWelcomeEmail(user);
}
}
// 好的写法 - 抽象层次一致
function processUser(userId) {
const user = getUser(userId);
if (isEligibleUser(user)) {
sendWelcomeEmail(user);
}
}
function isEligibleUser(user) {
return user.age > 18 &&
user.status === 'active' &&
!user.banned;
}
为什么要统一层次?
因为混搭会让逻辑跳跃,阅读代码的时候,大脑需要不断切换“焦距”。如果一会儿看到高层概念(发送邮件),一会儿又看到底层细节(判断年龄、状态),就会觉得很累。
最后
这些原则不是什么高深的理论,都是前人踩坑总结出来的经验。
其实好的代码就像好的文章:
-
结构清晰 :每个部分都有明确的作用
-
语言简洁 :用最简单的词表达清楚的意思
-
逻辑流畅 :读起来一气呵成,不用来回翻页
-
易于理解 :即使是外行人也能明白在说什么
记住这些原则,哪怕是 AI 生成的代码,也可以让它有质的飞跃!
我是冴羽,10 年笔耕不辍,专注前端领域,更新了 10+ 系列、300+ 篇原创技术文章,翻译过 Svelte、Solid.js、TypeScript 文档,著有小册《Next.js 开发指南》、《Svelte 开发指南》、《Astro 实战指南》。
欢迎围观我的“网页版朋友圈”,关注我的公众号:冴羽(或搜索 yayujs),每天分享前端知识、AI 干货。
更多推荐


所有评论(0)