今天的题目“看起来”没有任何的悬念。
请问点击第三个链接时弹出的值? <div id="demo"> <a href=http://item.feedsky.com/~feedsky/gracecode/~6159402/93957259/1221433/1/"#">A</a> <a href="#">B</a> <a href="#">C</a> <a href="#">D</a> </div> <script type="text/javascript"> var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; ++i) { nodes[i].onclick = function(ev) { alert(i * 100); } } } addHandlers(document.getElementById('demo').getElementsByTagName('a'));“很不幸”的是,上述的这段代码没有按照原意实现,点击它们所有的链接都是为 400。这是因为“点击以后执行 i * 100 ,而这个 i 是循环结束以后的值,按照上面的循环后值为 4”。
如果按照期望的写法,也就是点击链接以后 alert 不同的值,可以用闭包。比如下面有几个解决方案
var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; ++i) { (function () { var j = i * 100; nodes[i].onclick = function(ev) { alert(j); } }) (); } }“期前也讨论过,只不过那时还没有了解闭包,详细”。类似的题目,在《精通 Javascript》中 23 页(中文版)有提及。
var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; ++i) { nodes[i].onclick = function(idx) { return function(ev) { alert(idx * 100); } }(i); } }“另,如果是使用 YUI 的话,可能会更直观些”
var addHandlers = function(nodes) { for (var i = 0; i < nodes.length; ++i) { YAHOO.util.Event.on(nodes[i], 'click', function(ev, idx) { alert(idx * 100); }, i); } }使用闭包的话,必须注意两点:其一,就是避免出现无谓的匿名函数;其二,就是注意内存溢出。下面有几条有关闭包的参考链接。
Gracecode.com Permalink Trackback Wap Rss