如何在Lambda函数中访问外部数组?解决按钮点击弹窗异常问题
问题分析与解决方案
这是一个非常典型的闭包作用域陷阱问题,我来帮你拆解原因和解决办法:
为什么会弹出btnundefined?
循环里的click回调函数是异步执行的——只有当你点击按钮时,这段代码才会运行。但此时循环早就执行完毕了:循环条件是i<5,最后一次循环结束后i的值会变成5,而你的ids数组索引最大是4(对应值5),所以ids[i]就成了undefined,弹窗自然显示btnundefined。
三种可行的解决办法
1. 用立即执行函数(IIFE)创建独立作用域
通过立即执行函数把每次循环的i值“封存”在独立作用域里,让回调函数能访问到循环时的当前值:
<html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js "></script> <script type="text/javascript"> $(function(){ var ids=[1,2,3,4,5]; for(i=0;i<5;i++){ // 立即执行函数,传入当前循环的i (function(currentIndex){ $("#btn"+ids[currentIndex]).click(function(){ alert("btn"+ids[currentIndex]); }); })(i); } }); </script> </head> <body> <button id="btn1">按钮1</button> <button id="btn2">按钮2</button> <button id="btn3">按钮3</button> <button id="btn4">按钮4</button> <button id="btn5">按钮5</button> </body> </html>
2. 用ES6的let声明循环变量
let会在每次循环时创建一个新的块级作用域,自动保存当前的i值,完美规避闭包陷阱:
<html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js "></script> <script type="text/javascript"> $(function(){ var ids=[1,2,3,4,5]; // 用let替代var声明循环变量i for(let i=0;i<5;i++){ $("#btn"+ids[i]).click(function(){ alert("btn"+ids[i]); }); } }); </script> </head> <body> <button id="btn1">按钮1</button> <button id="btn2">按钮2</button> <button id="btn3">按钮3</button> <button id="btn4">按钮4</button> <button id="btn5">按钮5</button> </body> </html>
3. 利用jQuery的data()方法绑定值
把需要的ID值直接绑定到按钮元素上,点击时从元素本身读取,彻底绕开作用域问题:
<html> <head> <script type="text/javascript" src="https://code.jquery.com/jquery-3.3.1.min.js "></script> <script type="text/javascript"> $(function(){ var ids=[1,2,3,4,5]; for(i=0;i<5;i++){ $("#btn"+ids[i]) .data("btnId", ids[i]) // 将ID值绑定到按钮的data属性 .click(function(){ alert("btn"+$(this).data("btnId")); // 点击时读取绑定的值 }); } }); </script> </head> <body> <button id="btn1">按钮1</button> <button id="btn2">按钮2</button> <button id="btn3">按钮3</button> <button id="btn4">按钮4</button> <button id="btn5">按钮5</button> </body> </html>
核心思路
这几种方法的本质都是让每个点击回调函数能访问到循环执行时的当前值,而不是循环结束后的最终变量值。
内容的提问来源于stack exchange,提问作者Selenium
相关产品推荐
相关产品推荐

