4. JavaScript 编码规范:命名规范、注释规范与语句表达式规范
聊到 JavaScript 编码规范,我第一个想说的就是命名。
你想想看,代码写出来是给人看的。机器只关心对错,但人得看懂逻辑。我见过太多项目,变量名全是 a、b、temp、data,三个月后自己都看不懂写了啥。嗯,这其实是个大坑。
4.1 命名规范:让名字自己说话
4.1.1 变量命名
变量名要用小驼峰(camelCase)。说白了就是第一个单词小写,后面每个单词首字母大写。
我个人习惯是:名词或形容词+名词。比如:
// 好的命名
let userName = '张三';
let isLoggedIn = false;
let maxCount = 100;
let shoppingCart = [];
// 糟糕的命名
let a = '张三';
let flag = false;
let num = 100;
let arr = [];
我在项目中遇到过有人用 aaa、bbb 这种命名,结果代码 review 时被怼得很惨。记住:名字要能表达用途。
4.1.2 函数命名
函数名也是小驼峰。但函数是动作,所以要用动词开头。
// 好的函数名
function getUserData() { }
function calculateTotal() { }
function handleClick() { }
function validateEmail() { }
// 糟糕的函数名
function data() { }
function total() { }
function click() { }
我曾经接手过一个项目,有个函数叫 doSomething()。你猜它做了什么?它发了网络请求、更新了 DOM、还改了全局变量。嗯,这种命名等于没命名。
4.1.3 类与构造函数命名
类名用大驼峰(PascalCase)。每个单词首字母都大写。
class UserProfile { }
class ShoppingCart { }
class ApiService { }
为什么?因为看到大驼峰,你就知道这是个类,需要 new 来实例化。这是约定俗成的规矩。
_private 或 name_。虽然 JavaScript 允许,但这容易让人误解。我见过有人用 __proto__ 做变量名,结果踩了原型链的坑。
4.2 注释规范:JSDoc 让文档自动生成
注释不是越多越好。好的代码本身就能说明问题。但有些地方,注释是必须的。
4.2.1 什么时候需要注释
- 复杂的业务逻辑
- 别人看不懂的算法
- 临时修复(记得加 TODO)
- 函数和类的说明
4.2.2 JSDoc 的基本写法
JSDoc 是一种标准化的注释格式。它不光给人看,还能生成文档,IDE 也能识别。
/**
* 计算购物车总价
* @param {Array} items - 商品列表
* @param {number} items[].price - 单价
* @param {number} items[].count - 数量
* @param {number} [discount=0] - 折扣,可选,默认0
* @returns {number} 总价
*/
function calculateTotal(items, discount = 0) {
let total = items.reduce((sum, item) => {
return sum + item.price * item.count;
}, 0);
return total * (1 - discount);
}
我个人习惯是:每个导出函数都写 JSDoc。内部函数可以简单写。这样团队其他人调用时,鼠标悬停就能看到说明。
4.2.3 常用标签
| 标签 | 用途 | 示例 |
|---|---|---|
| @param | 参数说明 | @param {string} name - 用户名 |
| @returns | 返回值 | @returns {boolean} |
| @throws | 可能抛出的异常 | @throws {Error} 当参数无效时 |
| @deprecated | 标记废弃 | @deprecated 请使用新方法 |
| @example | 使用示例 | @example calculateTotal([...]) |
4.3 语句与表达式规范:写出整洁的代码
4.3.1 分号的使用
JavaScript 有自动分号插入机制。但我不建议依赖它。为什么?因为有些情况会出问题。
// 可能出问题的写法
let a = 1
(function() {
console.log('hello');
})();
// 上面会被解析成:
let a = 1(function() { ... })(); // 报错!
// 正确的写法
let a = 1;
(function() {
console.log('hello');
})();
我个人习惯:每行结尾都加分号。虽然有些团队不用分号,但加了更安全,也少了很多争议。
4.3.2 大括号与缩进
大括号不要省略。即使只有一行代码。
// 不推荐
if (condition) doSomething();
// 推荐
if (condition) {
doSomething();
}
缩进统一用 2 个空格。我见过用 4 个空格的,也见过用 Tab 的。说实话,这都可以。但关键是团队要统一。我们团队用 2 空格,因为嵌套深的时候看起来更清爽。
4.3.3 比较运算符
用 === 和 !==,不要用 == 和 !=。
// 坑人的 ==
console.log(0 == false); // true
console.log('' == false); // true
console.log(null == undefined); // true
// 用 === 更安全
console.log(0 === false); // false
console.log('' === false); // false
我记得有一次线上 bug,就是因为 == 把空字符串当成了 false,导致判断逻辑出错。从那以后,我要求团队必须用 ===。
4.3.4 字符串使用单引号
团队统一用单引号。除非字符串里包含单引号,才用双引号或模板字符串。
const name = '张三';
const message = '他说:"你好"';
const greeting = `你好,${name}`;
4.3.5 避免全局变量
不要污染全局作用域。用 let 和 const,别用 var。
// 不好的做法
var count = 0; // 全局变量
// 好的做法
const count = 0; // 块级作用域
const。只有确定变量会重新赋值时,才用 let。这样能避免很多意外修改。至于 var,我建议直接忘掉它。
4.4 总结一下
命名规范、注释规范、语句规范,这三件事看起来琐碎,但决定了代码的可维护性。
你想想看,一个项目少则几千行,多则几十万行。如果每个人按自己的习惯写,那代码就是一团乱麻。规范不是限制你,而是保护你。
嗯,最后送大家一句话:写代码时,想象一下三个月后的自己会怎么看这段代码。 如果你自己都看不懂,那别人更看不懂。