zoukankan      html  css  js  c++  java
  • JavaScript闭包示例

    在下面的例子中,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4。

     1 <html>
     2 <head>
     3 <meta charset="utf-8" />
     4 <title>闭包演示</title>
     5 <style type="text/css">
     6     p {background:#ccc;}
     7 </style>
     8 <script type="text/javascript">
     9 window.onload = function() {   
    10     var arr= document.getElementsByTagName("p");   
    11     for( var i=0; i<arr.length; i++ ) {   
    12          arr[i].onclick = function() {   
    13          alert(i);   
    14     }
    15   }
    16 }
    17 </script>
    18 </head>
    19 <body>
    20 <p>000</p>
    21 <p>111</p>
    22 <p>222</p>
    23 <p>333</p>
    24 <p>444</p>
    25 </body>
    26 </html> 

    原因是初学者并未理解JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元素添加 点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值 i,而是最后一次i++的值5。

    方法1:将变量 i 保存给在每个段落对象(p)上

    1  window.onload = function(){
    2     var arr = document.getElementsByTagName('p');
    3      for(var i=0; i<arr.length; i++){
    4          arr[i].i= i;  //或 arr[i].index = i;
    5              arr[i].onclick = function(){
    6              alert(this.i);  //或alert(this.index);
    7         }
    8      }
    9 }                

    方法2:加一层闭包,i 以函数参数形式传递给内层函数

    window.onload = function () {
      var arr= document.getElementsByTagName("p");
      for( var i=0; i<pAry.length; i++ ) {
       (function(arg){
           arr[i].onclick = function() {
              alert(arg);
           };
       })(i);//调用时参数
      }
    }

    方法3:将变量 i 保存在匿名函数自身

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

    4、加一层闭包,i 以局部变量形式传递给内层函数

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

    5、加一层闭包,返回一个函数作为响应事件(注意与2的细微区别)

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

    6、用Function实现,实际上每产生一个函数实例就会产生一个闭包

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

    7、用Function实现,注意与6的区别

    1 window.onload = function() {
    2     var arr= document.getElementsByTagName("p");
    3     for( var i=0; i<arr.length; i++ ) {
    4          arr[i].onclick = Function('alert('+i+')');
    5     }
    6 }
  • 相关阅读:
    《Effective Java》第9章 异常
    《Effective Java》第7章 方法
    《Effective Java》第6章 枚举和注解
    《Effective Java》第5章 泛型
    《Effective Java》第4章 类和接口
    《Effective Java》第3章 对于所有对象都通用的方法
    使用Spring加载properties配置文件.md
    第7章 插件的使用和写法
    第6章 jQuery与Ajax的应用
    第5章 jQuery对表单、表格的操作及更多应用
  • 原文地址:https://www.cnblogs.com/wxydigua/p/3238449.html
Copyright © 2011-2022 走看看