【原创】JS闭包的简单见解,新手向
网上有个问题到处都是,我是新手,自然也遇到了
问题如下:
请看下面的代码:为什么我无论点哪一个li标签,都会出出来:点击了第5个标签?
……
<script type="text/javascript"> window.onload = function(){ var lis = document.body.getElementsByTagName('li'); for(var i = 0; i < lis.length; i++){ lis[i].onclick = function(){ alert('点击了第'+i+'个标签'); } } } </script> <body> <ul id="ul"> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> </ul> </body> </html>
网上很多都是复制粘贴,有经验的JS程序员一看就懂,可苦了我这种新手。现在我写一点自己的理解也不知道对不对,如果有会的看到了,麻烦指正。
网上的答案大多是:
1.请看JS闭包
2.事实上循环没有为每个li绑定不同的方法
3.每个li绑定的方法都是一样的 function没被触发,触发时候里面的 i 是5
还让不让新手活了?
我自己看了一下,写一点见解。
reference:
http://hi.baidu.com/bluedream_119/item/938dcd082b1e18803d42e250
来看这段代码:
function a() { var i = 0; function b() { alert(++i); } return b; } var c = a(); c();
这是个闭包的典型例子。用了别人的总结:
1,闭包外层是个函数.
2,闭包内部都有函数.
3,闭包会return内部函数.
4,闭包返回的函数内部不能有return.(因为这样就真的结束了)
5,执行闭包后,闭包内部变量会存在,而闭包内部函数的内部变量不会存在.
外层函数:a()
内层函数:b()
我估计闭包范围就是从var i到return b 谁特么来帮我鉴定一下?
这里我们顺序执行:
前面函数a()那个是定义,不管。
第一句:var c=a();
执行了一次a(),i=0;学过C语言的知道a里的i,本应该被销毁的
但是函数a() return了b
那么c=b了,至此,“var c=a();” 执行完毕。
当函数a的内部函数b被函数a外的一个变量(这里就是例子里的C)引用的时候,就创建了一个我们通常所谓的“闭包”。
到这里可以了,闭包产生了,他的后果就是外函数内,内函数外的变量i变成全局变量了,哪怕a();早早执行完了
第二句:c();
前面说过 c被赋予了b的值,那么c();就是b();
所以alert(i)的结果是1 我估计如果再来一个c();结果应该是2
到这里可能很多人跟当时的我一样 看懂了这个经典的例子,但是一开始那个例子,为什么每次还是5,很多人还是不懂
我这里做个对应关系:
一开始的window.onload=function){} 对应例子2中的a()
for循环里的
lis[i].onclick = function(){ alert('点击了第'+i+'个标签'); }
对应的就是函数b(),
有人说,例子2中函数b被返回了 例子1没return啊?怎么回事?
其实例子1中的function 赋给了onclick这就是return了
而且onclick是函数a()外的一个变量,闭包达成!不信再看下定义
当函数a【例子1中是window.onload】的内部函数b【例子1中是function(alert)】被函数a外的一个变量C【lis[i].onclick】引用的时候,就创建了一个我们通常所谓的“闭包”。
这下明白了吧?
例子1 例子2的全局变量都是那个i 不因为外函数执行完而销毁失效
所以,那个i一直是5 自然每次都是5了
解决方案:
http://www.jb51.net/article/26553.htm
解决方案是怎么回事我有时间写
如果哪位高手发现我写错了 麻烦站内信我 我及时删帖