zoukankan      html  css  js  c++  java
  • 闭包-总结

    html

    <body onload="init();">
    	 <p>产品 0</p>
    	 <p>产品 1</p>
    	 <p>产品 2</p>
    	 <p>产品 3</p>
    	 <p>产品 4</p>
     </body>

    js

    function init() {
      var pAry = document.getElementsByTagName("p");
      for( var i=0; i<pAry.length; i++ ) {
          pAry[i].onclick = function() {
            alert(i);
          }  
      }
    }

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

    Javascript闭包的实现,通常是在函数内部再定义函数,让该内部函数使用上一级函数的变量或全局变量。
        子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
        既然f2可以读取f1中的局部变量,那么只要把f2作为返回值,我们不就可以在f1外部读取它的内部变量了吗!
        由于在Javascript语言中,只有函数内部的子函数才能读取局部变量,因此可以把闭包简单理解成“定义在一个函数内部的函数”。
        所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

    //将变量 i 保存给在每个段落对象(p)上

    function init1() {
         var pAry = document.getElementsByTagName("p");
         for( var i=0; i<pAry.length; i++ ) {
            pAry[i].i = i;
            pAry[i].onclick = function() {
               alert(this.i);
            }
         }
       }

    //将变量 i 保存在匿名函数自身

    function init2() {
         var pAry = document.getElementsByTagName("p");
         for( var i=0; i<pAry.length; i++ ) {
          (pAry[i].onclick = function() {
               alert(arguments.callee.i);
           }).i = i;
         }
       }

    //加一层闭包,i 以函数参数形式传递给内层函数

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

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

    function init4() {
         var pAry = document.getElementsByTagName("p");
         for (var i = 0; i < pAry.length; i++) {
           (function() {
             var temp = i; //调用时局部变量
             pAry[i].onclick = function() {
               alert(temp);
             }
           })();
         }
       }

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

       function init5() {
         var pAry = document.getElementsByTagName("p");
         for (var i = 0; i < pAry.length; i++) {
           pAry[i].onclick = function(arg) {
             return function() { //返回一个函数
               alert(arg);
             }
           }(i);
         }
       }

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

    function init6() {
           var pAry = document.getElementsByTagName("p");
           for( var i=0; i<pAry.length; i++ ) {
             pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例
           }
       }

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

    function init7() {
         var pAry = document.getElementsByTagName("p");
         for (var i = 0; i < pAry.length; i++) {
           pAry[i].onclick = Function('alert(' + i + ')');
         }
       }

    //第二种理解闭包

    var name = "The Window";
        var object = {
          name : "My Object",
          getNameFunc : function(){
            return function(){  //function是全局的,所以下面的this会指向window
              return this.name;
           };
          }
      };
      alert(object.getNameFunc()()); //The Window

    //2222

    var name = "The Window";
              var object = {
    
                name : "My Object",
    
                getNameFunc : function(name){
                  return function(){
                    return this.name;
                 }
                }('My Object')
           };
           alert(object.getNameFunc()); //My Object

    //end

  • 相关阅读:
    C# 时间格式化
    新线程匿名方法的新用法
    响应类
    图灵API
    Xpath使用
    Meta http-equiv属性
    CAC的Debian-8-64bit安装BBR正确打开方式
    CAC的Debian-8-64bit安装BBR正确方式是?
    Mbps Mb M Kb如何换算
    如何解决服务器远程桌面连接成功但重启却操作失效?
  • 原文地址:https://www.cnblogs.com/lisa2544/p/5513015.html
Copyright © 2011-2022 走看看