理解JavaScript闭包

发布于 2022-09-11 13:39:35 字数 4691 浏览 19 评论 0

  1. <ul>   
  2.         <li>1111</li>   
  3.         <li>2222</li>           
  4.         <li>3333</li>
  5. </ul>
  6. <script>
  7.         var a=document.getElementsByTagName('li');
  8.         for(var i=0,l=a.length;i<l;i++){        
  9.                 a[i].onclick=function(){            
  10.                         alert(i)        
  11.                 }   
  12.         }
  13. </script>

复制代码一个最经典的例子,上面的代码无论点击哪个结果都为最后的值,因为click事件接收的函数形成了一个闭包,闭包里的i只是对外部函数中变量i的引用,当fn执行完毕时变量i是循环得出的最后的值,闭包内的变量i也就是这个值了,所以不会依次弹出1,2.3.

至于解决的方法:

1)为遍历的每个元素添加自定义属性用来保存当前的索引值.

  1. function fn() {
  2.     var a = document.getElementsByTagName("li ");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         a[i].i = i;
  5.         a[i].onclick = function() {
  6.             alert(this.i);
  7.         }
  8.     }
  9. }

复制代码2)将当前索引值保存到匿名函数自身.

  1. function fn() {
  2.     var a = document.getElementsByTagName("li");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         (a[i].onclick = function() {
  5.             alert(arguments.callee.i);
  6.         }).i = i;
  7.     }
  8. }

复制代码3)加一层闭包,将当前索引值以函数参数形式传递到内部函数.

  1. function fn() {
  2.     var a = document.getElementsByTagName("li");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         (function(arg){
  5.             a[i].onclick = function() {
  6.                 alert(arg);
  7.             };
  8.         })(i);//调用时参数
  9.     }
  10. }

复制代码4)加一层闭包,将当前索引值以变量形式传递到内不函数.

  1. function fn() {
  2.     var a= document.getElementsByTagName("li");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         (function () {
  5.             var index = i;//调用时局部变量
  6.             a[i].onclick = function() {
  7.                 alert(index);
  8.             }
  9.         })();
  10.     }
  11. }

复制代码5)加一层闭包,返回一个函数作为响应事件.

  1. function fn() {
  2.     var a = document.getElementsByTagName("li");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         a[i].onclick = function(arg) {
  5.             return function() {//返回一个函数
  6.                 alert(arg);
  7.             }
  8.         }(i);
  9.     }
  10. }

复制代码6)利用Function对象,需要注意的是Function构造函数是在脚本运行时创建函数并将参数用作新函数的参数,所以相对前几种方法执行效率较低.

  1. function fn() {
  2.     var a = document.getElementsByTagName("li");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         a[i].onclick = Function('alert('+i+')')
  5.     }
  6. }

复制代码7)利用Function对象实例来产生闭包.

  1. function fn() {
  2.     var a= document.getElementsByTagName("li");
  3.     for( var i=0; i<a.length; i++ ) {
  4.         a[i].onclick = new Function('alert(' +i+' )' );//new一次就产生一个函数实例
  5.     }
  6. }

复制代码

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文