You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何MDN闭包for循环示例共享变量但自定义测试变量独立

核心差异本质:闭包捕获的变量所属的作用域不同

1. MDN示例的变量作用域逻辑

  • 你用var声明item时,var只有函数级作用域,没有块级作用域,所以整个setupHelp函数里只有唯一的一个item变量
  • 循环的每一轮都是给这个全局唯一的item重新赋值,三个onfocus回调作为闭包,捕获的都是同一个item的引用
  • 等你触发focus事件时,循环早就执行完了,item已经被赋值为helpText的最后一项,所以所有回调都拿到最后一条帮助文本

2. 你的测试代码的变量作用域逻辑

  • 你每次调用closure()函数时,都会在本次closure的函数作用域内,创建一个全新的独立的i变量
  • a对应的闭包来自第一次closure()调用,捕获的是第一个i;b对应的闭包来自第二次closure()调用,捕获的是第二个i
  • 两个i属于完全独立的函数作用域,互不干扰,自然修改一个不会影响另一个

常见修复方案

如果要让MDN的示例符合预期,有两种常用方法:

方法1:用let替代var声明循环变量

let有块级作用域,每轮循环都会创建一个独立的item变量,每个回调捕获的是当前轮次的独立item:

for (var i = 0; i < helpText.length; i++) {
  let item = helpText[i]; // 每轮循环创建新的item
  document.getElementById(item.id).onfocus = function() {
    showHelp(item.help);
  }
}

方法2:用立即执行函数(IIFE)创建独立作用域

每轮循环把当前item作为参数传入IIFE,生成独立的作用域保存当前值:

for (var i = 0; i < helpText.length; i++) {
  var item = helpText[i];
  (function(currentItem) {
    document.getElementById(item.id).onfocus = function() {
      showHelp(currentItem.help);
    }
  })(item)
}

内容的提问来源于stack exchange,提问作者khuongduy354

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 15:06:04