应明确区分前置与后置自增/自减的取值时机,避免在复合表达式中多次修改同一变量,将副作用限制在清晰、主动的位置,并优先使用显式控制的独立语句。

自增自减运算符本身就会产生副作用——它们直接修改变量值。所谓“避免副作用”,不是让它们不改值,而是让这种修改变得**可预期、可隔离、不干扰逻辑流**。
明确前置与后置的取值时机
副作用是否失控,关键在于你是否清楚“值什么时候被用”和“值什么时候被改”:
-
++i 和 --i:先改值,再返回新值。适合需要立即反映更新结果的场景,比如更新计数器后立刻渲染:
countEl.textContent = ++clickCount -
i++ 和 i--:先返回当前值,再改值。只应在“必须用旧值参与本次操作”的时候用,比如数组索引推进:
list.push(items[index++]) - 混淆两者会导致视觉延迟或越界:例如
tracker.innerHTML = i++首次点击显示0,实际i已变成1,但用户看不到——这是副作用“悄悄发生”的典型表现
禁止在复合表达式中多次修改同一变量
一行代码里对同一个变量用多次自增/自减,执行顺序依赖引擎实现,属于未定义行为:
分析 Java Spring Boot 后端 Controller 代码,自动生成 Markdown 格式的接口文档。当用户说“生成 Java 接口文档”、“生成 API 文档”、“从 Spring 代码生成文档”时触发。
- ❌ 避免:
sum = i++ + ++i、a[i++] = b[++i]——不同 JS 引擎可能得出不同结果 - ✅ 替代写法:拆成独立语句,显式控制时序
sum += a[i]; i++;<br>sum += b[j]; j++;
- for 循环第三部分已有
i++,就别在循环体内再写一遍,否则每次加 2,边界判断全失效
把副作用限制在清晰的位置
不要让自增操作藏在条件判断或赋值右侧深处,而应让它成为“主动动作”:
- ❌ 不推荐:
while (x > 0 && arr[i++] !== undefined)——i++在条件中执行,一旦越界就访问非法内存 - ✅ 更安全:
while (i 0) { /* 处理 arr[i] */ i++; } - 对敏感计数器(如帧序号、超时计数)加断言或日志:
console.assert(i
类型与边界要主动防护
自增自减不会报错,但溢出/下溢会静默改变逻辑:
- 有符号整型达到最大值后
++i会回绕为最小值;unsigned类型i = 0; i--得到极大值——这不是 bug,是标准行为,但业务上通常不可接受 - 用
BigInt处理大计数,或用if (i >= limit) break;提前终止,别依赖自动回绕 - 遍历数组时,优先用
for (let i = 0; i 而非while配合i++,减少手动维护索引出错概率
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










