标签:style blog http color os 使用 java io strong
闭包这个概念,一直都不太懂,现在也是。。。
前几天参加了阿里前端的在线笔试,有这样一道题:
有如下代码:
<p>p1</p> <p>p2</p> <p>p3</p> <p>p4</p> <p>p5</p> var ps = document.getElementsByTagName(‘p‘); for(var i = 0; i < ps.length; i++) { ps[i].onclick = function() { alert(i); } }
写出上述代码的运行结果,如果要输出 0 ~ length-1,如何修改代码,至少两种方法。
开始不知道在考什么,这两天在看书,才发现这样的问题其实是很常见的,泪奔~~
上面代码,依次单击,都会弹出5。
当
alert
被调用的时候,匿名函数保持对外部变量i
的引用,此时for
循环已经结束,i
的值被修改成了5
.
也就是说,每个p元素都绑定了单击事件,就是alert(i),但i的值在循环结束后已经变成5了,所以每一次单击都是弹出5。
那么如何一次弹出0,1,2,3,4,5呢,就需要每一次循环的时候把当前的i拷贝出来。
方法1就是使用立即执行函数:
for(var i = 0; i < ps.length; i++) { (function(e) { ps[i].onclick = function() { alert(e); } })(i); }
外部的匿名函数会立即执行,并把
i
作为它的参数,此时函数内e
变量就拥有了i
的一个拷贝。当传递给 单击的匿名函数执行时,它就拥有了对
e
的引用,而这个值是不会被循环改变的。
方法二是从匿名函数中返回一个函数:
for(var i = 0; i < ps.length; i++) { ps[i].onclick = (function(e) { return function() { alert(e); } })(i); }
参考:http://bonsaiden.github.io/JavaScript-Garden/zh/#function.closures
http://javascript.ruanyifeng.com/grammar/function.html#toc18
其实自己也是似懂非懂,不过我倒是写出了下面的方法,不知道是不是正规军。。。
在外层套一个父div,然后在div上添加单击事件。
<div> <p>p1</p> <p>p2</p> <p>p3</p> <p>p4</p> <p>p5</p> </div> var div = document.getElementsByTagName(‘div‘)[0]; var ps = document.getElementsByTagName(‘p‘); div.onclick = function(e) { for(var i = 0; i < ps.length; i++) { if(e.target == ps[i]) { alert(i); } } }
标签:style blog http color os 使用 java io strong
原文地址:http://www.cnblogs.com/zjzhome/p/3945319.html