代码如下:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>Untitled</title>
<script>
function func() {
var i;
for (i = 1; i <= 4; i++) {
var el = document.getElementById('closureExample' + i);
el.onclick = function() { alert(i) };
}
} window.onload = function() {
func();
}
</script>
</head><body>
<a href="#" id="closureExample1">例子1</a>
<a href="#" id="closureExample2">例子2</a>
<a href="#" id="closureExample3">例子3</a>
<a href="#" id="closureExample4">例子3</a>
</body>
</html>
我的本意:
是想单击例子1,例子2,例子3,例子4的时候,分别弹出1,2,3,4的,但是结果却发现弹出的都是5
我估计如下:
绑定的时候,是动态绑定的,只不过将事件绑定到了元素身上而已,但是参数却是在变的
当i==4的时候,由于运行了i++所以最终成了5 显示出来的结果当然是5了
我的猜想:
是不是在绑定的时候先运行一下click事件就可以解决这个问题呢?
现在寻求如何解决这一问题
<html>
<head>
<title>Untitled</title>
<script>
function func() {
var i;
for (i = 1; i <= 4; i++) {
var el = document.getElementById('closureExample' + i);
el.onclick = function() { alert(i) };
}
} window.onload = function() {
func();
}
</script>
</head><body>
<a href="#" id="closureExample1">例子1</a>
<a href="#" id="closureExample2">例子2</a>
<a href="#" id="closureExample3">例子3</a>
<a href="#" id="closureExample4">例子3</a>
</body>
</html>
我的本意:
是想单击例子1,例子2,例子3,例子4的时候,分别弹出1,2,3,4的,但是结果却发现弹出的都是5
我估计如下:
绑定的时候,是动态绑定的,只不过将事件绑定到了元素身上而已,但是参数却是在变的
当i==4的时候,由于运行了i++所以最终成了5 显示出来的结果当然是5了
我的猜想:
是不是在绑定的时候先运行一下click事件就可以解决这个问题呢?
现在寻求如何解决这一问题
==>
el.onclick = (function(n) {
return function() {alert(n);}
})(i)
<html>
<head>
<title>Untitled</title>
<script>
function func() {
var i;
for (i = 1; i <= 4; i++) {
document.getElementById("closureExample"+i).onclick = (function(n) {
return function() {alert(n);}
})(i)
}
} window.onload = function() {
func();
}
</script>
</head><body>
<a href="#" id="closureExample1">例子1</a>
<a href="#" id="closureExample2">例子2</a>
<a href="#" id="closureExample3">例子3</a>
<a href="#" id="closureExample4">例子3</a>
</body>
</html>
i的作用域是整个func函数。
在onclick的时候func函数内部的i已经是5了。
用cj锅那种形式,在i还是1/2/3/4/5的时候,分别传入匿名函数中,在匿名函数的环境中,存储了i在执行函数时的值,也就是分别是1 2 3 4 5
函数绑定的是变量i
但是循环结束之后i的值已经变了
这个时候你触发事件调用的i就是最大的值了
关于闭包 http://www.cn-cuckoo.com/2007/08/01/understand-javascript-closures-72.html 是最好的文档。
function func() {
for (var i = 1; i <= 4; i++) {
var el = document.getElementById('closureExample' + i);
el.setAttribute('index', i);
el.onclick = function() {
alert(this.getAttribute('index'));
};
}
}
for (i = 1; i <= 4; i++) {
var el = document.getElementById('closureExample' + i);
(function(){
var ii = i;
el.onclick = function(){ alert(ii);};
})();
}
}
for (var i = 1; i <= 4; i++) {
with ({i:i}) {
var el = document.getElementById('closureExample' + i);
el.onclick = function() { alert(i) };
}
}
}
new Array().fillRange(1,4).each(function(i){
document.getElementById("closureExample"+i).onclick = function(n) {
alert(i)
}})
var i;
for (i = 1; i <= 4; i++) {
var el = document.getElementById('closureExample' + i);
el.onclick = function() { alert(i) }; //这个函数的上下文是func函数,这样onclick能访问func函数定义的i变量,他没有绑定那个值,只是能访问上下文的变量,这样最终执行onclick时i已经在这个上下文中有固定值5,所以全部onclick都显示5
}
}
这是活的
el.onclick = (function(n) {
return function() {alert(n);}
})(i)
这是死的这样理解就直观了
这样只创建了一层闭包,alert显示的变量i就是外层函数里的局部变量,循环结束之后,他的值被改变成5了,所以,触发点击事件的时候引用的还是这个变量,其值是5
el.onclick = (function(n) {
return function() {alert(n);}
})(i)
这种 做法创建了两层闭包,alert显示的变量在匿名函数里的参数,他是以参数的形式传递进来的,后面也没有操作改变这个值,所以一次点击会有不同的值,实际上与上面不同的是,alert显示的i引用了不同的变量,而上面的例子却引用了相同的变量