JavaScript for循环与闭包:解决点击事件输出错误的7种方案
作者:木棉时间:2026-10-30 09:32:07浏览:522
本文深入解析JavaScript中for循环绑定点击事件时输出固定值的经典问题。通过7种不同方案,包括变量挂载、函数参数传递、立即执行函数及Function构造函数等,详细展示如何利用闭包机制正确捕获循环变量,确保每次点击输出对应索引。
问题背景:for循环与点击事件的经典陷阱
有开发者提出一个常见疑问:在如下HTML结构中,为什么每次点击段落元素时,弹出的数值始终是5,而不是期望的对应索引1、2、3、4、5?
<html >
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>闭包演示</title>
<script type="text/javascript">
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function() {
alert(i);
}
}
}
</script>
</head>
<body onload="init();">
<p>产品一</p>
<p>产品二</p>
<p>产品三</p>
<p>产品四</p>
<p>产品五</p>
</body>
</html>
解决方案详解
针对该问题,存在多种解决思路。
方案一:将变量 i 保存给在每个段落对象(p)上
第一种方案是将变量 i 保存给在每个段落对象(p)上
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].i = i;
pAry[i].onclick = function() {
alert(this.i);
}
}
}
方案二:将变量 i 保存在匿名函数自身
第二种方案是将变量 i 保存在匿名函数自身
function init2() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(pAry[i].onclick = function() {
alert(arguments.callee.i);
}).i = i;
}
}
方案三:加一层闭包,i以函数参数形式传递给内层函数
第三种方案是加一层闭包,i以函数参数形式传递给内层函数
function init3() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(function(arg){
pAry[i].onclick = function() {
alert(arg);
};
})(i);//调用时参数
}
}
方案四:加一层闭包,i以局部变量形式传递给内存函数
第四种方案是加一层闭包,i以局部变量形式传递给内存函数
function init4() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(function () {
var temp = i;//调用时局部变量
pAry[i].onclick = function() {
alert(temp);
}
})();
}
}
方案五:加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
第五种方案是加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
function init5() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function(arg) {
return function() {//返回一个函数
alert(arg);
}
}(i);
}
}
方案六:用Function实现,实际上每产生一个函数实例就会产生一个闭包
第六种方案是用Function实现,实际上每产生一个函数实例就会产生一个闭包
function init6() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例
}
}
方案七:用Function实现,注意与6的区别
第七种方案是用Function实现,注意与6的区别
function init7() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = Function('alert('+i+')')
}
}
以上就是小编为大家带来的浅谈JavaScript for循环 闭包全部内容了,希望大家多多支持本站~
作者最新文章
JS合并多个数组的三种方法:concat、spread与flat
2026-11-05 17:39:45
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
