理解JS中的闭包

之前看到一个观点是  闭包是走向高级Javascript的必经之路,之前看过很多关于闭包的讲解帖子,一直没有理解透彻,模棱两可。

现在终于可以讲出来了。

检验自己有没有掌握一个知识,最好的方式是讲给一个不懂的人 ,给Ta讲懂了。我做到了。

请有心读者检阅我的知识点有么有错误。

一:什么闭包

首先要理解 js特殊的作用域机制:只能按照作用域链向上访问,而不能访问Ta下级域中的变量。

闭包:就是能够读取其他函数内部变量的函数。 (*^__^*) 

一切函数某种环境下都可以当做闭包。

手写一个demo:

     function a(){

        var s = 1;

        function b(){

           s++;

        } 

    }

上述中   b函数就是一个闭包。

二:闭包的用途:

   1.可以读取函数内部的变量   2  使这些变量保存在内存中

举栗子:

var li = document.getElementsByTagName("li");
    for(var i=0;i<5;i++){
         li[i].onclick = function(){
         alert(i);
    }
}

 这样运行结果是:每次弹出5;   原因是:当点击alert  i的值为最后运算完的值。

修改方法一:

   匿名函数自调用;

var li = document.getElementsByTagName("li");
for(var i=0;i<5;i++){
      (function(arg){
          li[i].onclick = function(){
            alert(arg);
         }
      })(i);
}

-----------------分割线  -------------------

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

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

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

1
2
3
4
5
6
7
8
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;  
 }  
}

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

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

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

1
2
3
4
5
6
7
8
9
10
11
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);   
   }  
  })();  
 }  
}  

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

1
2
3
4
5
6
7
8
9
10
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);  
 }  

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

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

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

1
2
3
4
5
6
function init7() {  
  var pAry = document.getElementsByTagName("p");  
  for( var i=0; i<pAry.length; i++ ) {  
     pAry[i].onclick = Function('alert('+i+')'
  }  
}
posted @ 2017-05-01 12:27  红色柠檬  阅读(243)  评论(0编辑  收藏  举报