JSA注释规范:写好注释的8个黄金法则,让你的代码会说话
发布时间:2026-02-14 06:27 浏览量:2
你的代码真的需要注释吗?90%的注释都是废话!今天教你写出真正有价值的注释
上周看团队里一个同事的代码,600行一个注释都没有。问他这段逻辑是干啥的,他盯着屏幕看了5分钟,说:“我好像也忘了...”
另一个极端:有人给i++这种代码写注释“将i的值增加1” —— 这种注释比没有还糟!
今天,我用8个黄金法则,教你写出真正有价值的注释,让你的代码自己会说话。
先看看这些“经典”反面教材:
JavaScript
// ❌ 废话型let i = 0; // 将i设置为0i++; // i加1// ❌ 迷惑型// 这里处理特殊情况if (data.length > 5) {// 不要问我为什么是5,产品经理说这样写processData(data);}// ❌ 过时型// 2023-01-15 张三:临时方案,后面要改(现在都2024年了)function fixBug(data) {// ...}// ❌ 情绪型// 妈的,这段代码千万不要动,谁动谁改bugfunction mysteriousFunction {// 我也看不懂,但能跑}
JavaScript
// ✅ 复杂业务逻辑function 计算年终奖(员工) {// 年终奖计算公式:基础工资 * 系数A + 绩效 * 系数B// 其中系数A取决于入职年限,系数B取决于全年绩效// 具体算法详见《2024年薪酬管理制度》第3.2节// ... 复杂的计算逻辑}// ✅ 特殊算法解释function 排序数据(数组) {// 使用快速排序的变种,针对Excel数据特点优化// 当数组长度小于50时,改用插入排序(实测性能提升15%)// ... 算法实现}// ✅ 临时解决方案// 2024-03-15 张三:临时处理WPS JSA的Bug// WPS 12.1版本中,直接使用Range.Value会丢失格式// 改用Range.Text + Range.Value2组合获取function 安全获取值(cell) {// ... 临时方案}// ✅ 外部依赖说明// 此函数依赖【人员信息.xlsx】工作簿的结构// 必须包含:姓名(A列)、工号(B列)、部门(C列)、入职日期(D列)function 导入人员信息 {// ...}
代码 = 逻辑 × 表达
注释 = 为什么 × 怎么用
代码负责说“怎么做”注释负责说“为什么做”和“什么情况下做”
JavaScript
// ✅ 好注释:解释意图,而不是动作function 验证年龄(年龄) {// 年龄不能为负数,这是业务规则if (年龄 60) {return 跳过考核;}}// ❌ 烂注释:描述代码本身function 验证年龄(年龄) {// 判断年龄是否小于0if (年龄
JavaScript
// 规范1:注释和代码之间空一格let 总数 = 100; // 初始数量// 规范2:注释单独一行时,上方空一行(可选)function 计算总额(价格, 数量) {// 价格和数量必须为正数if (价格
JavaScript
/*** 计算员工月度工资(函数功能简要说明)* * 详细说明:根据员工基础工资、出勤天数、绩效系数综合计算* 特殊处理:管理层有额外补贴,实习生不参与绩效计算* * @param {Object} 员工信息 - 包含员工所有信息的对象* @param {number} 员工信息.基础工资 - 员工基础月薪(元)* @param {number} 员工信息.出勤天数 - 本月实际出勤天数* @param {number} 员工信息.绩效系数 - 0.8-1.5之间的系数* @param {string} 员工信息.职位类型 - '管理'、'普通'、'实习'* @param {Date} 计算月份 - 计算的月份(用于判断节假日)* @returns {Object} 计算结果,包含应发工资、扣款明细等* @throws {Error} 当基础工资为负数时抛出错误* * @example* // 计算普通员工1月工资* const 结果 = 计算工资({* 基础工资: 10000,* 出勤天数: 22,* 绩效系数: 1.2,* 职位类型: '普通'* }, new Date('2024-01-01'));* * @since 1.0.0* @author 张三* @lastUpdate 2024-03-15*/function 计算工资(员工信息, 计算月份) {// 函数实现...}
JavaScript
/*** 文件名:salary_calculator.js* 描述:工资计算模块,处理员工工资相关逻辑* * 主要功能:* 1. 月度工资计算* 2. 年终奖计算* 3. 五险一金扣除* 4. 个税计算* * 依赖文件:* - config/ salary_config.js (工资配置参数)* - data/ employee_data.xlsx (员工基础数据)* * 修改记录:* v1.0.0 2024-01-01 张三 初始版本* v1.1.0 2024-02-15 李四 增加年终奖计算功能* v1.2.0 2024-03-10 王五 修复个税计算Bug* * 注意事项:* 1. 此模块依赖外部配置文件,运行时需确保配置文件存在* 2. 大数据量计算时建议关闭屏幕更新以提升性能* 3. 涉及金额计算时统一使用分单位,避免浮点数精度问题* /
JavaScript
function 处理复杂报表 {/* ========= 第一阶段:数据清洗 ========= */// 1. 去除空行// 2. 统一日期格式// 3. 处理异常值/* ========= 第二阶段:数据计算 ========= */// 注意:以下计算涉及多个表的关联// 需要先计算A表,再计算B表,最后合并// 具体算法参见《报表开发文档》第5章/* ========= 第三阶段:结果输出 ========= */// 输出格式要求:// - 金额保留两位小数// - 百分比显示为xx.xx%// - 负数用红色括号表示}
JavaScript
// ❌ 烂注释:描述whatlet maxRetry = 3; // 最大重试次数设为3// ✅ 好注释:解释whylet maxRetry = 3; // 根据服务器配置,超过3次会被限流,所以设3次// ❌ 烂注释:描述howif (数据.length > 1000) {批量处理; // 如果数据超过1000条,用批量处理}// ✅ 好注释:解释whyif (数据.length > 1000) {批量处理; // 实测单条处理1000条以上时内存溢出,改用批量}// ❌ 烂注释:重复代码i++; // i加1// ✅ 好注释:解释业务含义i++; // 移动到下一条记录(因为表头占一行)
JavaScript
function 计算库存预警(商品) {// 为什么用7天?因为供应商平均补货周期是7天// 低于7天的库存可能造成断货let 安全库存 = 商品.日均销量 * 7;// 为什么用3天?这是公司规定的最低警戒线// 低于3天必须立即补货let 警戒库存 = 商品.日均销量 * 3;if (商品.库存
JavaScript
// 错误示例:注释没更新/*** 计算旧版工资(员工信息格式:姓名,工号,基础工资)* @param {Array} 员工数组 - [姓名, 工号, 基础工资]*/function 计算工资(员工信息) {// 但实际上参数已经改成对象了// 员工信息 = { 姓名, 工号, 基础工资, 部门, 入职日期 }// 这段代码已经跑不起来了!let 基础工资 = 员工信息[2]; // ❌ 现在员工信息[2]是undefined}
JavaScript
// 修改前的注释// v1.0 简单计算:工资 = 基础工资 + 奖金function 计算工资(员工) {return 员工.基础工资 + 员工.奖金;}// 修改时同步更新注释/*** v1.1 修改为:工资 = 基础工资 * 绩效系数 + 奖金 - 扣款* 修改原因:2024年新薪酬制度引入绩效系数* 修改人:张三* 修改日期:2024-03-15*/function 计算工资(员工) {// 绩效系数范围0.8-1.5,低于0.8按0.8算let 绩效系数 = Math.max(0.8, Math.min(1.5, 员工.绩效系数));return 员工.基础工资 * 绩效系数 + 员工.奖金 - 员工.扣款;}
JavaScript
// [版本1.0] 2024-01-01 张三 创建function 旧方法 {// ...}// [版本2.0] 2024-03-15 李四 重构:改用新算法提升性能function 新方法 {// 旧算法在数据量>10000时性能下降,改用二分查找// 性能测试:处理10万条数据从3秒降到0.5秒}// [临时补丁] 2024-03-20 王五 紧急修复线上Bug// 问题:当客户名称包含特殊字符时导出失败// 解决方案:增加encodeURIComponent处理
JavaScript
function 处理大数据 {// TODO 2024-04-01 张三:此处需要优化性能// 当前算法时间复杂度O(n²),数据量>1000时卡顿// 计划改用哈希表优化到O(n)for (let i = 0; i
JavaScript
function 计算总额(项目列表) {let 总额 = 0;// FIXME 2024-03-15 张三:浮点数精度问题// 当项目包含0.1+0.2时,计算结果为0.30000000000000004// 需要改用整数计算或toFixed处理项目列表.forEach(项目 => {总额 += 项目.金额; // 这里会有精度问题});// FIXME(紧急) 2024-03-20 李四:内存泄漏// 连续调用此函数100次以上导致内存溢出// 需要检查是否有全局变量未释放创建临时对象; // 怀疑这里有问题return 总额;}
JavaScript
function 导入数据(文件路径) {// NOTE 此函数依赖外部文件编码格式// 文件必须是UTF-8编码,ANSI编码会乱码let 数据 = 读取文件(文件路径);// NOTE 性能敏感:此操作会锁定文件,耗时较长// 建议在非工作时间运行处理大数据;// NOTE 已知问题:文件名不能包含中文// 这是WPS JSA的限制,已在官方反馈保存文件(文件路径 + "_已处理");}
JavaScript
function 复杂计算(参数) {// DEBUG: 查看输入参数console.log("输入参数:", JSON.stringify(参数));let 结果 = 0;// DEBUG: 查看每一步计算结果let 中间结果1 = 步骤1(参数);console.log("步骤1结果:", 中间结果1);let 中间结果2 = 步骤2(中间结果1);console.log("步骤2结果:", 中间结果2);// DEBUG: 检查边界条件if (中间结果2
JavaScript
/*** ===== 维护指南 =====* * 如果你需要修改这个函数,请注意:* * 1. 依赖关系* - 函数A依赖于这个函数* - 报表B直接调用此函数* 修改返回值格式会影响其他模块* * 2. 性能要求* - 必须在1秒内返回结果* - 不能使用递归(会导致堆栈溢出)* * 3. 特殊数据* - 当id为null时,表示新员工* - 当工资为0时,可能是实习生或离职人员* * 4. 测试用例* - 正常情况:普通员工* - 边界情况:新员工、离职员工* - 异常情况:数据缺失、格式错误* * 如有疑问,请联系作者:张三(内线8001)*/
JavaScript
// 针对【初级开发者】的注释/*** 这是基础的数据清洗函数* * 新手注意:* 1. 这里用到了正则表达式,如果不熟悉可以先看看文档* 2. 数组的map方法会返回新数组,不影响原数组* 3. 记得处理空值情况*/function 清洗数据(原始数据) {// 先用filter去掉空值let 非空数据 = 原始数据.filter(item => item !== null && item !== undefined);// 再用map转换格式return 非空数据.map(item => ({id: item[0],name: item[1].trim,value: parseFloat(item[2])}));}// 针对【业务人员】的注释/*** 月度销售报表生成函数* * 业务逻辑说明:* 1. 只统计已确认的订单(状态为'已完成')* 2. 按销售区域分组统计* 3. 计算各区域完成率 = 实际销售额 / 目标销售额* 4. 完成率低于80%的标红显示* * 输出格式参考《销售报表规范V2.3》*/function 生成销售报表(月份) {// ...}
JavaScript
// ❌ 太啰嗦/*** 这个函数是用来计算两个数字相加的结果的,它接收两个参数,* 这两个参数都是数字类型,如果不是数字类型可能会报错,* 然后函数会返回这两个数字相加的和,如果传的参数不是数字,* 返回的结果会是NaN,也就是Not a Number的意思...*/function add(a, b) {return a + b;}// ✅ 简洁清晰/*** 两数相加* @param {number} a - 加数* @param {number} b - 加数* @returns {number} 两数之和* @throws {TypeError} 当参数不是数字时抛出错误*/function add(a, b) {if (typeof a !== 'number' || typeof b !== 'number') {throw new TypeError('参数必须是数字');}return a + b;}
JavaScript
// // 模块一:数据验证// 负责所有输入数据的合法性检查// /*** 验证手机号格式* @param {string} phone - 11位手机号* @returns {boolean} 是否有效*/function 验证手机号(phone) {return /^1[3-9]\d{9}$/.test(phone);}/*** 验证邮箱格式* @param {string} email - 邮箱地址* @returns {boolean} 是否有效*/function 验证邮箱(email) {return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);}// // 模块二:数据格式化// 负责将数据转换为显示格式// /*** 格式化金额* @param {number} amount - 金额(分)* @returns {string} 格式化后的金额(元)*/function 格式化金额(amount) {return '¥' + (amount / 100).toFixed(2);}
JavaScript
/*** @fileoverview 员工管理模块* @author 张三* @version 1.0.0* @license MIT*//*** @class 员工类* @classdesc 表示一个员工的实体类* @property {string} name - 员工姓名* @property {string} id - 员工工号* @property {number} salary - 员工工资*/class 员工 {/*** 创建员工实例* @constructor* @param {string} name - 姓名* @param {string} id - 工号* @param {number} salary - 工资*/constructor(name, id, salary) {this.name = name;this.id = id;this.salary = salary;}/*** 计算员工年度奖金* @param {number} performance - 绩效评分(0-100)* @returns {number} 年度奖金金额* @throws {Error} 当绩效评分超出范围时抛出*/计算年终奖(performance) {if (performance 100) {throw new Error('绩效评分必须在0-100之间');}return this.salary * (performance / 100);}}/*** @deprecated 已废弃,请使用新版的EmployeeManager类* @see EmployeeManager*/function 旧版员工管理 {// ...}
JavaScript
function 操作Excel {// WPS JSA特有:关闭屏幕更新提升性能Application.ScreenUpdating = false;// WPS特有方法:获取当前选中区域let selection = Application.Selection;// 注意:JSA中Range的值需要用Value2获取// Value2比Value更快,且不会返回错误值let cellValue = selection.Value2;// 特殊说明:WPS 12.1版本中,Cells和Range有差异// 建议统一使用Range方式,兼容性更好let cell1 = Range("A1"); // ✅ 推荐let cell2 = Cells(1, 1); // ⚠️ 有些版本可能有问题// 恢复屏幕更新Application.ScreenUpdating = true;}/*** 获取工作簿中的所有工作表名称* * 兼容性说明:* - WPS 2019 及以上版本:完全支持* - WPS 2016:部分支持(不支持Sheets.Count属性)* - Office 2013 及以上版本:完全支持* * 如果运行环境不支持,请升级到WPS 2019以上版本* * @returns {Array} 工作表名称数组 */ function 获取所有工作表名 { let 名称列表 = ; let wb = Application.ActiveWorkbook; // 兼容WPS 2016的写法 try { for (let i = 1; i
JavaScript
// 处理数据function a(b) {let c = ;for (let i = 0; i 0) {c.push(b[i] * 1.2);}}return c;}// 计算总额function d(e) {let f = 0;for (let i = 0; i /*** 处理销售数据:过滤并计算提成* * 业务规则:* 1. 只处理正数销售额(负数可能是退款,不计算提成)* 2. 提成比例固定为20%(乘以1.2)* 3. 返回处理后的提成金额数组* * @param {Array} 原始销售额 - 销售记录数组,单位:元 * @returns {Array} 提成金额数组,单位:元 * * @example * // 销售额为[100, -50, 200]时,返回[120, 240] * 计算提成([100, -50, 200]); */ function 计算提成(原始销售额) { let 提成金额 = ; for (let i = 0; i 0) { // 提成比例20%(2024年新政策) 提成金额.push(原始销售额[i] * 1.2); } } return 提成金额; } /** * 计算提成总额 * * 将提成金额数组求和,得到总提成金额 * * @param {Array} 提成数组 - 各笔交易的提成金额 * @returns {number} 提成总额 * * @see 计算提成 */ function 计算提成总额(提成数组) { let 总额 = 0; for (let i = 0; i
最后,记住这句话:
好代码是自解释的,好注释是补充说明的。
点赞 支持更多技术干货关注我 ➕ 第一时间获取JSA系列教程分享 让更多同事写出会“说话”的代码