Vanilla JS点击演员按钮始终显示最后一个数组对象问题求助
问题原因及解决方法
这是典型的闭包作用域陷阱。如果你的代码里用var声明循环变量(比如for (var i = 0; i < actors.length; i++)),var声明的变量属于函数级作用域,循环结束后所有按钮的点击事件回调都会共享同一个变量引用,最终指向数组的最后一个演员数据。
下面是几种可行的解决方法:
方法1:用let声明循环变量
let是块级作用域,每次循环都会创建新的变量绑定,确保每个按钮的点击事件引用的是当前迭代的演员:
fetch('actors.json') .then(response => response.json()) .then(actors => { const container = document.getElementById('actor-buttons'); for (let i = 0; i < actors.length; i++) { const actor = actors[i]; const button = document.createElement('button'); button.textContent = actor.name; button.addEventListener('click', () => { // 这里处理显示当前演员电影信息的逻辑 console.log(actor.movies); }); container.appendChild(button); } });
方法2:使用forEach遍历数组
forEach的回调函数会为每个元素创建独立作用域,从根源避免共享变量的问题:
fetch('actors.json') .then(response => response.json()) .then(actors => { const container = document.getElementById('actor-buttons'); actors.forEach(actor => { const button = document.createElement('button'); button.textContent = actor.name; button.addEventListener('click', () => { console.log(actor.movies); // 处理显示电影信息 }); container.appendChild(button); }); });
方法3:用立即执行函数(IIFE)绑定当前变量
如果环境不支持ES6的let,可以用立即执行函数把当前迭代的演员数据封装起来:
fetch('actors.json') .then(response => response.json()) .then(actors => { const container = document.getElementById('actor-buttons'); for (var i = 0; i < actors.length; i++) { (function(currentActor) { const button = document.createElement('button'); button.textContent = currentActor.name; button.addEventListener('click', () => { console.log(currentActor.movies); // 处理显示电影信息 }); container.appendChild(button); })(actors[i]); } });
内容的提问来源于stack exchange,提问作者Emma Pasquer
相关产品推荐
相关产品推荐

