
本文详解 `i++` 与 `++i` 的本质区别,指出因误用后置递增/递减导致计数器首次点击失效的问题,并提供修复方案、边界防护及最佳实践。
在 JavaScript 中,i++(后置递增)和 ++i(前置递增)虽仅差一个位置,语义却截然不同:
- i++ 先返回当前值,再将 i 加 1;
- ++i 先将 i 加 1,再返回新值。
你遇到的“首次点击不更新数字、第二次才生效”问题,根源正在于此:
tracker.innerHTML = i++; // ❌ 错误:赋值的是旧值 i,之后 i 才 +1
例如初始 i = 0:
- 第一次点击 donate → tracker.innerHTML = 0(显示 0),然后 i 变为 1;
- 第二次点击 → tracker.innerHTML = 1(显示 1),然后 i 变为 2;
→ 表现为“延迟一帧更新”,且状态与 UI 显示严重脱节。
✅ 正确写法是使用前置递增/递减,确保赋值即同步最新值:
立即学习“Java免费学习笔记(深入)”;
const donateButton = document.getElementById("donate");
const unDonateButton = document.getElementById("undonate");
const tracker = document.getElementById("container");
let i = 0; // 推荐用 let 替代 var
tracker.textContent = i; // 使用 textContent 更安全(防 XSS)
donateButton.addEventListener("click", () => {
donateButton.style.backgroundColor = "red";
unDonateButton.style.backgroundColor = ""; // 重置另一按钮样式
tracker.textContent = ++i; // ✅ 立即更新并显示新值
});
unDonateButton.addEventListener("click", () => {
if (i > 0) {
unDonateButton.style.backgroundColor = "blue";
donateButton.style.backgroundColor = ""; // 重置另一按钮样式
tracker.textContent = --i; // ✅ 安全递减
} else {
alert("Cannot undonate: quantity is already zero!");
}
});⚠️ 关键注意事项:
- 永远校验边界:undonate 操作必须检查 i > 0,避免数量变为负数;
- 样式互斥管理:切换按钮时应主动清除另一按钮背景色,否则会出现“红+蓝”残留;
- 避免全局变量污染:将 i 封装进 IIFE 或模块作用域更佳;
- 优先使用 textContent:比 innerHTML 更安全、性能更好(无 HTML 解析开销);
- 事件监听推荐箭头函数或具名函数:避免隐式全局变量(原代码中 donate = function(){} 会意外创建全局 donate)。
总结:看似微小的 i++ 与 ++i 差异,实则是值传递时机的根本分歧。理解运算符求值顺序,是写出可预测、可维护前端逻辑的第一步。










