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

循环内绑定DOM元素事件时,所有事件触发输出相同key的问题求助

解决循环中绑定事件时变量引用统一的问题

这个问题是JavaScript里非常经典的函数作用域陷阱,我来帮你理清楚原因和解决办法:

问题根源

你在循环里用了var key来声明变量,但var是函数作用域(或者全局作用域)的变量——也就是说整个循环里其实只有一个key变量,每次循环只是更新它的值。当点击事件触发时,循环早就执行完了,key已经被赋值为循环的最后一个属性名,所以所有点击事件里的console.log(key)都会打印同一个结果。

三种解决方案

方案1:用let代替var(最简洁)

let是ES6引入的块级作用域变量,每次循环都会创建一个全新的key变量,每个点击事件都会捕获当前循环迭代的那个key值:

var dom = {}; 
var popupContent = L.DomUtil.create('div'); 
// 把var替换成let
for(let key in this._info){ 
 dom[key] = L.DomUtil.create('a', "", popupContent); 
 dom[key].innerHTML = key; 
 dom[key].href = "#"; 
 L.DomEvent.on(dom[key], 'click', function(){ 
   // do some stuff 
   console.log(key); 
 }); 
} 
var popup = L.popup(); 
popup.setLatLng(latlng) 
 .setContent(popupContent) 
 .openOn(this._map); 

方案2:用闭包保存当前变量值(兼容旧环境)

如果需要兼容不支持ES6的环境,可以用立即执行函数表达式(IIFE)创建独立作用域,把当前循环的key值传递进去:

var dom = {}; 
var popupContent = L.DomUtil.create('div'); 
for(var key in this._info){ 
 dom[key] = L.DomUtil.create('a', "", popupContent); 
 dom[key].innerHTML = key; 
 dom[key].href = "#"; 
 // 用IIFE包裹,传入当前key作为参数
 (function(currentKey) {
   L.DomEvent.on(dom[key], 'click', function(){ 
     // do some stuff 
     console.log(currentKey); 
   }); 
 })(key);
} 
var popup = L.popup(); 
popup.setLatLng(latlng) 
 .setContent(popupContent) 
 .openOn(this._map); 

方案3:用forEach遍历(更现代的写法)

可以把for...in换成Object.entries配合forEach,forEach的每个回调函数都有独立的作用域,能自然保存当前的key值:

var dom = {}; 
var popupContent = L.DomUtil.create('div'); 
// 遍历对象的键值对
Object.entries(this._info).forEach(([key]) => {
 dom[key] = L.DomUtil.create('a', "", popupContent); 
 dom[key].innerHTML = key; 
 dom[key].href = "#"; 
 L.DomEvent.on(dom[key], 'click', function(){ 
   // do some stuff 
   console.log(key); 
 }); 
});
var popup = L.popup(); 
popup.setLatLng(latlng) 
 .setContent(popupContent) 
 .openOn(this._map); 

总结

推荐优先使用方案1(let)或者方案3(forEach),代码更简洁易读,也符合现代JavaScript的写法。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:47:21