写给自学前端同学的编程法则
你可能想:“现在都是 AI 写代码了,有必要学这个吗?” 确实,AI 确实很强大,但它有 2 个致命的局限: 1. AI 生成的代码质量参差不齐 AI 是根据概率生成代码的,它并不知道什么是“好的代码”。如果你不告诉它,它可能会给你生成一个把所有逻辑都塞在一起的千行函数——看似能跑,实则维护噩梦。 2. 和 AI 对话需要清晰的思路 想让 AI 帮你写出好代码,你首先得知道“好代码”长什么样。 这些编程原则就是你和 AI 沟通的“语言”: 不懂原则,你就无法判断 AI 给的东西好不好,更没法指导 AI 改进。 AI 改变了写代码的方式,但没有改变好代码的标准。 以前,你手写代码,考验的是打字速度和语法记忆。现在,你和 AI 协作,考验的是: 这些能力的基础,就是我今天要分享的这些编程原则。 很多新手有个通病:一上来就想写出“完美”的代码。 结果呢?代码越写越复杂,时间越花越多,最后反而写不出好用的代码。 说句大实话:先让它跑起来,再说别的。 由此诞生了三次法则。具体怎么做: 为什么要这样呢? 因为只有写了三遍,你才能真正明白: 简单说,就是别想太多,先写起来再说。 写代码要遵循这个步骤: 别管代码多丑,先让功能正常运行;别担心性能问题,先确保逻辑正确;别想架构问题,先把基本功能实现。 补充测试用例,确保各种边缘情况都能处理。 进行性能优化。 很多时候,你会发现根本走不到第三步。 因为大部分场景下,“够用”就行了。 好的函数就像好的工具:专一、高效、易用。 一个函数应该只负责一件事,就像螺丝刀只负责拧螺丝,锤子只负责敲钉子。 比如这样一段代码: 一个函数做了 5 件不同的事情:获取数据、筛选、发邮件、统计、记录日志。 其实应该拆成: 使用这种方式: 听起来很专业,其实很简单:同样的输入,每次都得到同样的输出。 举个例子: 之所以要这样做,是因为在真实的开发场景里,很多操作可能会被重复执行: 如果你的代码不是幂等的,这些情况都可能出问题。 简单说就是:同一个函数里,代码的“颗粒度”要保持一致。 举个例子: 为什么要统一层次? 因为混搭会让逻辑跳跃,阅读代码的时候,大脑需要不断切换“焦距”。如果一会儿看到高层概念(发送邮件),一会儿又看到底层细节(判断年龄、状态),就会觉得很累。 这些原则不是什么高深的理论,都是前人踩坑总结出来的经验。 其实好的代码就像好的文章: 记住这些原则,哪怕是 AI 生成的代码,也可以让它有质的飞跃! 我是冴羽,10 年笔耕不辍,专注前端领域,更新了 10+ 系列、300+ 篇原创技术文章,翻译过 Svelte、Solid.js、TypeScript 文档,著有小册《Next.js 开发指南》、《Svelte 开发指南》、《Astro 实战指南》。 欢迎围观我的“网页版朋友圈”,关注我的公众号:冴羽(或搜索 yayujs),每天分享前端知识、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} 个活跃用户`);
}// 拆分成多个专一的函数
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;
}最后