Closure Understanding Daquan------I believe you will understand closures better! ! !

Closure concept: It means that in JavaScript, inner functions can always be accessed - parameters and variables declared in their local scope can still be accessed even after their local scope is destroyed.

Closure function: A function defined in the local scope.

The essence of closure: the local variables outside the closure function are resident in memory. (In the program, avoid using global variables, it is recommended to use private, encapsulated local variables)

Disadvantage: memory leak (any object still exists after you no longer need it).

Features of closures: 1. Functions are nested within functions; 2. Inner functions can reference outer parameters and variables; 3. Parameters and variables will not be recycled by the garbage collection mechanism.

The following 1 and 2 examples are for the understanding of the concept, the rest are some exercises, with the anonymous function self-execution in the next chapter, I hope you will have a deeper understanding of closures:

1. Access data outside the function inside the function
            var a = 1; //global variable
            function fn_01(){
                alert(a);
            }
            fn_01(); //1             function fn_02(){                 var num = 10;             }             fn_02() ;             alert(num); //num is not defined              //If the outside wants to access the local private variables inside the function, it cannot be accessed directly             //Because the local variables will be destroyed after the function runs, which uses the closure. (The closure function can be accessed) 2. Access local variables through the closure             function fn_01(){                 var num = 3; //variable                 return function(){ //closure function                     return num;                 }             }
          







            







            alert( fn_01()() ); //The closure function accesses the variable in the local scope             function fn_02(num){ //Parameter var num Formal parameter (formal parameter): The parameter that receives the data when the function is defined. Actual parameters (actual parameters): The parameters passed when calling the function.                 return function(){ //The closure function                     return num;                 }             }             alert( fn_02(4)() ); //The closure function accesses the parameters in the local scope
            





3. The value problem of the anonymous function in the loop
            function fn_01(){
                var arr = [];
                for(var i = 0;i < 5;i++){
                    arr[i] = function(){ //The function is not executed , without taking the value of i outside, only assigning the function block to the array arr
                        return i;        
                    }
                }
                return arr;
            }
            alert( fn_01() );  
/*Explanation: The array arr loops 5 times and stores the function anonymous function in In the array, the function does not execute
            function(){
                return i;
            },function(){
                return i;
            },function(){
                return i;
            },function(){
                return i;
            },function(){
                return i;
            }

*/
       //自己执行
            function fn_02(){
                var arr = [];
                for(var i = 0;i < 5;i++){
                    arr[i] = (function(){
                        return i;
                    })();            //让闭包函数自执行,每次执行,都将i存放在数组arr中
                }
                return arr;
            }
            alert( fn_02() );    //arr = [0,1,2,3,4];

  //传参数
            function fn_03(){
                var arr = [];
                for(var i = 0;i<5;i++){
                    arr[i] = (function(i){
                        return i;    
                    })(i)                 //函数执行,返回循环每一次i的值,作为参数,传递给闭包函数,返回值i,传递给数组
                }
                return arr;
            }
            //alert(fn_04());
            var list = fn_04();
            for(var j = 0,len = list.length;j < len;j++){
                alert(list[j]);       //返回数组是[0,1,2,3,4]
            }
          //传参数加 闭包函数
           function fn_04(){
                var arr = [];
                for(var i = 0;i<5;i++){
                    arr[i] = (function(i){     //闭包函数
                        return function(){    //闭包函数    
                            return i;
                        };
                    })(i)              //函数执行,返回循环每一次i的值,作为参数,传递给闭包函数,返回值i,传递给数组
                }
                return arr;
                                    //此时arr数组存放的是function(){return i;}这个函数块  取值的时候,向上面的父级函数取i,这里的i传递的参数是循环变量每次的i
            }
            //alert(fn_04());
            var list = fn_04();
            for(var j = 0,len = list.length;j < len;j++){
               alert(list[j]());   
            }
           
练习题 1. fn(1)(2)(3)   使用闭包得到6
            function fn(x){
                
                return function(y){
                    
                    return function(z){
                        
                        alert(x+y+z);
                    }
                }
            }
            fn(1)(2)(3);
练习题 2.
            var name = "jack";
            var obj = {
                name: "Lisa",
                getName : function(){
                    return function(){     //闭包  
                        return this.name;
                    }
                }
            }
            alert( obj.getName()() );   
            
            var name = "jack";
            var obj = {
                name: "Lisa",
                getName :function(){
                    var that = this;        //this 指向obj
                    return function(){
                        return that.name;
                    }
                }                                                
            }
            alert( obj.getName()() );                                   
      
练习题 3.三个数的累加,要求:同时支持下面两种写法
            //sum(1)(2)(3)  使用闭包得到6
            //sum(1,2,3);
            var sum = (...a)=>{  //a表示所有的参数
                if(a.length == 3;){
                    return a[0] + a[1] + a[2];
                }else{
                    var x = a[0];
                    return function(y){
                        return function(z){
                            return x + y + z;
                        }
                    }
                }
            }
            alert( sum(1,2,3) );
            alert( sum(1)(2)(3) );
            
练习题 4.点击按钮,让按钮里面的值++

<style type="text/css">
 #btn{
       width:80px;
       height:30px;
       font-size: 16px;
 }
</style>
 <input type="button" value="0" id="btn"/>

         var oBtn = document.getElementById("btn")
         oBtn.onclick = function(){
                this.value = Number(this.value) + 1;
          }
            //闭包写法实现
            (function(){
                var i = Number(oBtn.value);
                oBtn.onclick = function(){
                    this.value = ++ i;
                }
            })() //减少全局变量 

          function fn_06(){
                var i = 0;
                return function(){
                    return ++ i;
                }
            }
            var n = fn_06();
            oBtn.onclick = function(){
                this.value = n();
            }


            //循环加计时器--闭包解决   
            for (var i=1; i<=9; i++) {
                setTimeout( function timer(){
                    console.log( i );
                },1000 );
            }

    /*解释  i = 0  ...覆盖 1,2,3,4   
              setTimeout(function(){console.log(i);},0)  //计时器,是延时操作,即使事件是0,也排在后面执行(异步)
              setTimeout(function(){console.log(i);},0)
              setTimeout(function(){console.log(i);},0)
              setTimeout(function(){console.log(i);},0)
              setTimeout(function(){console.log(i);},0)
                最后 i = 5  不执行下面了,  所以输出5个5  */

  //闭包解决
            for (var i=1; i<=9; i++) {
                (function(j){
                    setTimeout( function timer(){
                        console.log( j );
                    }, 1000 );
                })( i );
             }  

       //let 也可以解决(详解可以看前几章关于for循环中有关let的解释)

    for(let i = 0;i < 5;i ++){
                    setTimeout(function(){
                      console.log(i);
                   },0)        
             }
          /*      i=0
                setTimeout(function(){console.log(i);},0)
                i=1
                setTimeout(function(){console.log(i);},0)  .....i=2 i=3 i=4   */


这是 一道面试题,如何更改下面的代码,将a[6] 输出的结果得到6 ?
            var a=[];
            for(var i=0;i<10;i++){
                a.push(
                    function(){console.log(i)}
                );
            }
            a[6]();  //10
            
            var a=[];
            for(let i=0;i<10;i++){
                a.push(
                    function(){console.log(i)}
                );
            }
            a[6](); // 6
            
            var a=[];
            for(var i=0;i<10;i++){
                a.push(
                    function(i){
                        return function(){
                            console.log(i);
                        }
                    }(i)
                );
            }
            a[6]();  //6

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325419398&siteId=291194637