理解JavaScript闭包
- <ul>
- <li>1111</li>
- <li>2222</li>
- <li>3333</li>
- </ul>
- <script>
- var a=document.getElementsByTagName('li');
- for(var i=0,l=a.length;i<l;i++){
- a[i].onclick=function(){
- alert(i)
- }
- }
- </script>
复制代码一个最经典的例子,上面的代码无论点击哪个结果都为最后的值,因为click事件接收的函数形成了一个闭包,闭包里的i只是对外部函数中变量i的引用,当fn执行完毕时变量i是循环得出的最后的值,闭包内的变量i也就是这个值了,所以不会依次弹出1,2.3.
至于解决的方法:
1)为遍历的每个元素添加自定义属性用来保存当前的索引值.
- function fn() {
- var a = document.getElementsByTagName("li ");
- for( var i=0; i<a.length; i++ ) {
- a[i].i = i;
- a[i].onclick = function() {
- alert(this.i);
- }
- }
- }
复制代码2)将当前索引值保存到匿名函数自身.
- function fn() {
- var a = document.getElementsByTagName("li");
- for( var i=0; i<a.length; i++ ) {
- (a[i].onclick = function() {
- alert(arguments.callee.i);
- }).i = i;
- }
- }
复制代码3)加一层闭包,将当前索引值以函数参数形式传递到内部函数.
- function fn() {
- var a = document.getElementsByTagName("li");
- for( var i=0; i<a.length; i++ ) {
- (function(arg){
- a[i].onclick = function() {
- alert(arg);
- };
- })(i);//调用时参数
- }
- }
复制代码4)加一层闭包,将当前索引值以变量形式传递到内不函数.
- function fn() {
- var a= document.getElementsByTagName("li");
- for( var i=0; i<a.length; i++ ) {
- (function () {
- var index = i;//调用时局部变量
- a[i].onclick = function() {
- alert(index);
- }
- })();
- }
- }
复制代码5)加一层闭包,返回一个函数作为响应事件.
- function fn() {
- var a = document.getElementsByTagName("li");
- for( var i=0; i<a.length; i++ ) {
- a[i].onclick = function(arg) {
- return function() {//返回一个函数
- alert(arg);
- }
- }(i);
- }
- }
复制代码6)利用Function对象,需要注意的是Function构造函数是在脚本运行时创建函数并将参数用作新函数的参数,所以相对前几种方法执行效率较低.
- function fn() {
- var a = document.getElementsByTagName("li");
- for( var i=0; i<a.length; i++ ) {
- a[i].onclick = Function('alert('+i+')')
- }
- }
复制代码7)利用Function对象实例来产生闭包.
- function fn() {
- var a= document.getElementsByTagName("li");
- for( var i=0; i<a.length; i++ ) {
- a[i].onclick = new Function('alert(' +i+' )' );//new一次就产生一个函数实例
- }
- }
复制代码
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论