• 闭包


    一、闭包定义

      函数嵌套函数,子函数访问父函数的变量,就产生了一个闭包环境
                function fn1(){
                    var n=10;    //n是在函数内声明的,局部变量,它在函数外面是访问不到的
                    function fn2(){        //fn2是在函数内声明的,局部函数,它在函数外面是访问不到的
                        n++;
                        console.log(n);            //11
                    }
                    fn2();
                }
                //fn2(); 这里是不能够访问到fn2的函数
                fn1();    //11
                fn1();    //11
                //console.log(n);        //报错
                那么如何让局部域的变量和函数,在全局被访问到?
    二、生命周期与垃圾回收机制
                              生命周期
                 *         变量或者函数在相应的作用域里存在的时间
                 *         局部变量:不再使用了,就是生命周期的结束。局部变量是在函数内声明的,当函数执行完成以后,这个变量就不存在了
                 *         全局变量:声明完成以后,在整个页面中都可以用。当页面关闭的时候,它的生命周期就结束了
     
                 *         垃圾回收机制
                 *         变量存在内存当中的,变量在使用完以后,没有在其它的地方再使用,就会被清除,用来释放内存。垃圾回收机制会按照固定                            的时间,周期性的执行
         1.     function fn1(){
                    var b=12;
                }
                fn1();        
                
                //console.log(b);        //报错 变量b在函数fn1执行完成以后,发现在别的地方没有再使用,那它就会被垃圾回收机制所回收
                //就是局部作用是基于垃圾回收机制的
     
         2.     function fn2(){
                    var n=10;
                    function fn3(){
                        n++;
                        console.log(n);
                    }
                    fn3();
                }
                fn2();        //11
                fn2();        //11
                //fn2函数在执行完成以后,变量n在其它的地方没有被使用,所以n在fn2执行完成以后会被垃圾回收机制 所回收。再去设fn2的时候,此时内存当中已经没有n这个变量了,只不过是重新声明了一个n
     
    三、闭包的作用
             让函数内的局部变量与局部函数,在外面(不一定是全局变量,只是相对于该局部的)可以访问到
           方法有两种
            1、定义一个全局变量,放入到局部域里面,然后将需要的局部变量和函数赋值给它,然后再全局就能调用。
                var innerFn=null;        //全局变量,用来存储内部函数
                function fn1(){
                    var n=10;
                    function fn2(){
                        n++;//n=n+1
                        console.log(n);
                    }
                    fn2();       //这里执行了函数之后得到的结果就是一个数
                    
                    innerFn=fn2;  
                }
                fn1();        //11
                
                innerFn();        //12        把fn2整个函数赋给了innerFn,而它本身就是一个全局变量,有了值以后在其它的地方就可以访问到它了
                innerFn();        //13          因为fn2变成了全局变量,因此它的变量没有被垃圾回收机制回收。因此不断累加
     
                  2、将局部变量以及函数从局部域调出到全局域,那么在外面就能访问到了。      
                function fn1(){
                    var n=10;
                    function fn2(){
                        n++;
                        console.log(n);
                    }
                    
                    return fn2;    //这里的意思是把fn2返回到了fn1的结果, 既是fn1()=function fn2(){};
                }
                console.log(fn1());        //fn1()=function fn2(){};
                var newFn=fn1();
                /* 相当于 var newFn=function fn2(){    相当于将fn2从局部的函数调出到了全局。并且把函数说明变成函数表达式
                         n++;
                         console.log(n);
                }*/
                newFn();        //11
                newFn();        //12
     
    四、闭包的应用
            1.在循环中找到对应的值
    1. window.onload=function(){
    2. var lis=document.querySelectorAll('li');
    3. //var i=0;
    4. for(var i=0;i<lis.length;i++){
    5. //利用作用域访问的关系。不让i访问到for
    6. lis[i].onclick=(function(i){
    7. //这里给的形参就说明在这个局部域里面有i,所以找值得时候,找到这里就停了,不用找到上面一层for的i, for的i永远是length
    8. function fn2(){
    9. console.log(i);
    10. }
    11. return fn2;
    12. })(i); //相当于把fn2从里里面的域带了出现,但是i的值还是从里面开始查找起。
    13. }
    14. }
    15. <ul>
    16. <li>red</li>
    17. <li>green</li>
    18. <li>blue</li>
    19. <li>yellow</li>
    20. <li>pink</li>
    21. </ul>
     
  • 相关阅读:
    匹配@之前面的部分
    把一个数字的字符串转换为千分符的标识方式?
    下标重置
    linux的time命令

    常用正则
    正则
    PHP 菠菜木马代码
    PHP 木马代码,
    一句话的木马
  • 原文地址:https://www.cnblogs.com/CafeMing/p/6438470.html
Copyright © 2020-2023  润新知