zoukankan      html  css  js  c++  java
  • 理解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+')'
      }  
    }
  • 相关阅读:
    LeetCode 485. Max Consecutive Ones
    LeetCode 367. Valid Perfect Square
    LeetCode 375. Guess Number Higher or Lower II
    LeetCode 374. Guess Number Higher or Lower
    LeetCode Word Pattern II
    LeetCode Arranging Coins
    LeetCode 422. Valid Word Square
    Session 共享
    java NIO
    非阻塞IO
  • 原文地址:https://www.cnblogs.com/liuliang-wifi/p/6791497.html
Copyright © 2011-2022 走看看