
本文解析 javascript 中 `i++` 与 `++i`(以及 `i--` 与 `--i`)的本质差异,说明为何在事件处理中误用后置递增/递减会导致“首次点击无效”等反直觉行为,并提供正确写法与健壮实践。
问题的核心在于对后置递增/递减运算符(i++ / i--)执行时机的理解偏差。
在你的原始代码中:
tracker.innerHTML = i++;
这行语句的执行顺序是:
也就是说,i++ 返回的是自增前的旧值。因此,第一次点击时:
这就解释了“需两次点击才显示变化”的现象。同理,i-- 也返回旧值,导致递减逻辑同样滞后一帧。
✅ 正确做法是使用前置递增/递减运算符(++i / --i):它先修改变量值,再返回新值。
同时,为避免食物数量变为负数,undonate 还应添加边界校验:
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),且语义更清晰
const donate = () => {
donateButton.style.backgroundColor = 'red';
tracker.textContent = ++i; // 先 +1,再赋值显示
};
const undonate = () => {
if (i > 0) {
unDonateButton.style.backgroundColor = 'blue';
tracker.textContent = --i; // 先 -1,再赋值显示
} else {
// 可选:视觉反馈提示已达下限
unDonateButton.style.backgroundColor = '#ccc';
setTimeout(() => {
unDonateButton.style.backgroundColor = '';
}, 300);
}
};
donateButton.addEventListener("click", donate);
unDonateButton.addEventListener("click", undonate);? 关键总结:
掌握这一细微却关键的语法差异,能帮你避开大量看似“玄学”的状态同步 bug。