闭包-总结

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

原文地址:https://www.cnblogs.com/lisa2544/p/5513015.html