初识闭包

 

闭包

当内部函数被保存在外部,会生成闭包。 这会造成父函数生成的AO不被释放,占据内存空间。这会造成内存泄漏。
内存泄漏:由于内存大量被使用,计算机的可用内存像泄漏了一样,导致可用内存少。

闭包的作用

    • 实现共有变量:都存在父函数的AO里
    • 可以做缓存:父函数的AO当缓存用
    • 函数封装,实现私有化
    • 模块化开发,防止污染全局变量
    function a() {
        function b() {
            var bbb = 234;
            document.write(aaa);
        }
        var aaa = 123;
        return b;
    }

    var glob = 100;
    var demo = a();
    // 123。虽然a()执行结束,a应该销毁了自己的AO。
    // 但是b生在于AO,而a的AO被引用在b的执行期上下文中,b保存了a的当前AO。
    // a不再引用自己生成的AO,下次a执行会创建新的AO病2使用。
    // 这就是【闭包】。
    demo(); 
    // 内部函数被保存到外部,就会生成闭包。

    function a1() {
        var num = 100;
        function b() {
            num++;
            console.log(num);
        }
        return b;
    }
    // 调用a1,最后a执行完之前demo1被赋值b。a1销毁。
    var demo1 = a1();
    // 这样b就脱离原来的a1了。调用b,a1不再执行了,num = 100+1, 返回101
    demo1();
    // 再调用b,a1不再执行,不会重新初始化num,num=101+1, 返回102
    demo1();


    // 闭包的应用-共有变量:累加器,更加结构化
    function add() {
        var count = 0;
        function d(){
            count ++;
            console.log(count);
        }
        return d;
    }
    var counter = add();
    counter();
    counter();
    counter();

    // 闭包的应用-缓存:myArr内元素公用一个t生成的AO
    function t(){
        var num=100;
        function a() {
            num ++;
            console.log(num);
        }

        function b() {
            num --;
            console.log(num);
        }

        return [a,b];
    }
    var myArr = t();
    myArr[0]; // 100 + 1 = 101
    myArr[1]; // 101 - 1 = 100

    // 闭包的应用-缓存:将obj缓存
    function eater() {
        var food = "";
        var obj = {
            eat: function() {
                console.log(`I am eating ${food}`);
                food = "";
            },
            push: function(myFood) {
                food = myFood;
            }
        }
        return obj;
    }
    var eater1 = eater();
    eater1.push("Food");
    eater1.eat();

  
   function test(){
        var arr = [];
        // 把function添加入数组
        for(var i = 0; i < 10; i ++) {
            // 立即执行函数要记住末尾加括号表示参数!!
            (function(){
                console.log(i);
                arr[10+i] = function () {
                // 函数内在下面myArr调用的时候才执行
                document.write(i + " - ");
            }
            }());
            /* function只有在执行的时候才会执行内部代码,引用的时候不执行 */
            arr[i] = function () {
                // 函数内在下面myArr调用的时候才执行
                document.write(i + " - ");
            }
            
        }
        return arr;
    }
    
    var myArr = test();
    // 下面都是10,因为 i 已经再test的AO里固定了,执行完for循环后,由于i++,i增长为10
    myArr[0](); 
    myArr[1]();
    myArr[2]();
    myArr[10]();
    myArr[11]();
    myArr[12]();
 
  
   // 立即执行函数防闭包,须在html里面添加li
    function addLi() {
        var lis = document.getElementsByTagName('li');
        for(var i = 0; i < lis.length; i++){
            // 立即执行函数内部的函数也立即执行而不需要调用再执行
            // 因此可以立即在内部执行,避免闭包
            console.log(i);
            (function(j){
                lis[j].onclick = function() {
                    console.log(j);
                }
            }(i));
        }
    }
    addLi();
 
  
 
  
 

 

posted @ 2020-11-27 19:14  SvenWayne  阅读(70)  评论(0)    收藏  举报