闭包函数栗子

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

<script>
    function outer(){
        var scope="outer";
        function inner(){
            return scope;
        }
        return inner;
    }
    var fn=outer();
    console.log(fn());
</script>

图

运行结束由于fn指向了inner ,inner拿着scope chain的拷贝、所以outer的AO没有释放

图

闭包的危险

闭包会造成原有的AO不释放,产生内存泄漏。

这里的内存泄露,指的事非正规的内存的占用。内存泄漏是源于英文的翻译,内存是源于硬件泄漏描述的不合理,是内存使用的不合理得不到释放。

闭包的引用

<script>
    //实现共有变量
    //累加器
    function add(){
        var count=0;
        function addAction(){
            count++;
            console.log(count);
            return count;
        }
        return addAction;
    }
    var myAdd= add();
    myAdd();
    myAdd();
    myAdd();
</script>
<script>
    //缓存存储结构
    function add(){
        var count=0;
        function addAction(){
            count++;
            console.log(count);
            return count;
        }
        function clearAction(){
            count=0;
            console.log(count);
        }
        return [addAction,clearAction];
    }
    var myAdd= add();
    myAdd[0]();
    myAdd[0]();
    myAdd[0]();
    myAdd[1]();
</script>
<script>
    //使用方法操作变量、模块化操作,避免了变量的污染
    function add(){
        var count=0;
        var adder={
            addAction: function(){
            count++;
            console.log(count);
            return count;
            },
            clearAction:function (){
                count=0;
                console.log(count);
                return count;
            }
        };

        return adder;
    }
    var myAdd= add();
    myAdd.addAction();
    myAdd.addAction();
    myAdd.addAction();
    myAdd.clearAction();
    myAdd.addAction();
</script>

列题

<script>
    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]());
    console.log(fn[1]());
    /**
     * outer()声明:脚本的scope chain ->copy [GO] ,生成自己的:[GO,outer-AO]
     * result[0]=function(){}:outer的scope chain -> copy [GO,outer-AO] ,没有运行
     * result[1]=function(){}:outer的scope chain -> copy [GO,outer-AO] ,没有运行
     */
</script>

注意:函数的表达式和声明是不一样的,表达式是在运行时copy的scope chain。函数声明拿到的scope chain是在预编译。所以当result运行时 i已经等于2了

Last modification:January 30, 2020
如果觉得我的文章对你有用,请随意赞赏