为什么“整洁代码”关乎金钱和时间,而非美学
\n\n想象一下,你打开一个别人的JavaScript项目。变量名是a、b、x1。函数长达300行。条件嵌套得像套娃一样。熟悉吗?如果你曾诅咒过这样的“作者”,那么你已经明白为什么需要整洁代码了。
JavaScript中的整洁代码并非追求时尚或完美主义者的任性。它是一种工具,能节省数小时的调试时间,简化新人的入职流程,并降低项目的维护成本。在本文中,我们将探讨具体的规则和技巧,帮助你编写不仅机器能理解,人类也能读懂的代码。
\n\n规则1:变量和函数名应能自解释
\n\n新手最常见的错误是使用简短且无意义的名称。糟糕的例子:
\n\nlet d = new Date();\nlet n = d.getDay();\nlet r = n === 0 || n === 6 ? '周末' : '工作日';\nconsole.log(r);\n\n\n好的例子:
\n\nconst currentDate = new Date();\nconst dayOfWeek = currentDate.getDay();\nconst isWeekend = dayOfWeek === 0 || dayOfWeek === 6;\nconst dayType = isWeekend ? '周末' : '工作日';\nconsole.log(dayType);\n\n\n区别显而易见。在第二个版本中,我们无需额外注释就能立即理解代码的功能。建议:变量使用名词,函数使用动词。例如:getUserData()、calculateTotal()、isValidEmail()。
如何避免“魔法数字”?
\n\n魔法数字是指那些没有上下文就无法理解其含义的数字。请使用常量代替它们:
\n\n// 糟糕\nif (user.role === 1) { ... }\n\n// 好\nconst ROLE_ADMIN = 1;\nif (user.role === ROLE_ADMIN) { ... }\n\n\n规则2:函数应短小精悍,只做一件事
\n\n单一职责原则不仅适用于类,也适用于函数。如果一个函数做了三件事,它就应该被拆分成三个函数。糟糕的例子:
\n\nfunction processOrder(order) {\n // 验证\n if (!order.items || order.items.length === 0) {\n throw new Error('购物车为空');\n }\n // 计算折扣\n let discount = 0;\n if (order.total > 1000) {\n discount = 0.1;\n }\n // 发送邮件\n sendEmail(order.email, '您的订单已接收');\n return order.total - order.total * discount;\n}\n\n\n好的例子(重构后):
\n\nfunction validateOrder(order) {\n if (!order.items || order.items.length === 0) {\n throw new Error('购物车为空');\n }\n}\n\nfunction calculateDiscount(total) {\n return total > 1000 ? 0.1 : 0;\n}\n\nfunction notifyCustomer(email) {\n sendEmail(email, '您的订单已接收');\n}\n\nfunction processOrder(order) {\n validateOrder(order);\n const discount = calculateDiscount(order.total);\n notifyCustomer(order.email);\n return order.total - order.total * discount;\n}\n\n\n这种结构使得每个部分易于单独测试,并且可以在不影响其他代码的情况下更改逻辑。
\n\n规则3:避免深层嵌套
\n\n嵌套层级越多(if里面套if,再套for),代码就越难读。请使用提前返回和卫语句。
\n\n// 糟糕\nfunction getUserDisplayName(user) {\n if (user) {\n if (user.name) {\n if (user.name.length > 0) {\n return user.name;\n }\n }\n }\n return '匿名';\n}\n\n// 好\nfunction getUserDisplayName(user) {\n if (!user || !user.name || user.name.length === 0) {\n return '匿名';\n }\n return use