闭包

函数的ao通过scope chain相互连接起来使得函数体内的变量都可以保存在函数的AO,这样的特性称为“闭包”。

什么时候会产生闭包?

只要你把一个函数里面的函数,作为 return 的方式返回到外边,扔给一个变量。只要做这个事刚才的调用就产生了闭包。

闭包的危险

闭包会造成原有ao不释放,产生内存泄漏,或者说是内存不合理占用。

闭包原理图解

闭包形成原理及应用-LMLPHP
闭包形成原理及应用-LMLPHP
闭包形成原理及应用-LMLPHP

闭包形成原理及应用-LMLPHP
因为outer Activation object 一直不能释放,就形成了一个闭包

闭包的应用

1,实现公有变量

     //累加器
  function  add(){
    var conut = 0;
    function addAction(){
        conut++;
        console.log(conut);
        return conut;
    }
        return addAction();
    }

    var myadd = add();
    myadd();
    myadd();
    myadd();
    myadd([1]);
    myadd();

2, 缓存存储结构

     function  add(){
    var conut = 0;
    function addAction(){
        conut++;
        console.log(conut);
        return conut;
    }
    function clearAction(){
        conut=0;
        console.log(conut);
        return conut;
    }
    return [addAction,clearAction];
    }

    var myadd = add();
    myadd[0]();
    myadd[0]();
    myadd[0]();
    myadd[0]();
    myadd[1]();
    myadd[0]();
    myadd[0]();

3, 封装,实现属性私有化
//鼓励使用方法,不鼓励直接操作变量

    function  counter(){
        var conut = 0;
        var adder= {
            addAction: function () {
                conut++;
                console.log(conut);
                return conut;
            },

            clearAction: function () {
                conut=0;
                console.log(conut);
                return conut;
            }
        };
        return adder;
    }

    var myCounter = counter();
    myCounter.addAction();
    myCounter.addAction();
    myCounter.addAction();
    myCounter.addAction();
    myCounter.clearAction();
    myCounter.addAction();
    myCounter.addAction();
    myCounter.addAction();
    myCounter.addAction();

4,模块化开发,防止污染全局变量
如果我们从别人的地方copy过来的代码的变量和自己的变量重复,两段代码分开都运行正常,但是放到一起可能就会出错,所以用闭包的方法把他们封装在一个函数里面返回出来,就可以避免这种情况发生。

在大型公司模块化开发,全部使用闭包,不允许使用公有变量



练习1 面试题

    function outer(){
        var num=100;
        function add(){
            num++;
            console.log(num);
        }
            return add;
    }
    var fn= outer();
    fn();// 101
    fn();//102
    fn();//103

    var fn2= outer();
    fn2();// 104
    fn2();// 105

练习2 面试题

    function outer(){
        var result= new Array();
        for (var i = 0;i< 2;i++){
            result[i] = function(){
                return i;
            };
        }
        return result
    }
    var fn = outer();
    console.log(fn[0]()); // 2
    console.log(fn[1]()); // 2

分析
闭包形成原理及应用-LMLPHP
解决上面这种问题的思路

  1. 立即执行函数
  2. 立即执行函数内部再声明函数
    function outer(){
        var result= new Array();
        for (var i = 0;i< 2;i++){
            result[i] = function(x){
                function f2(){
                return x;
                }
                return f2;
            }(i);
        }
        return result
    }
    var fn = outer();
    console.log(fn[0]()); // 0
    console.log(fn[1]()); // 1
08-10 19:56