js函数--闭包

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>函数--闭包</title>
</head>
<body>
    <script>
        /*
            javascript函数--闭包:
                全局变量可以通过闭包实现局部私有。
                有权访问父作用域的函数,即使在父函数关闭后。
                一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。
                也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域。
                在 JavaScript 中,每当创建一个函数,闭包就会在函数创建的同时被创建出来。
        */
        /*
            1.执行上下文
            2.闭包
            3.闭包用途
        */

        //1.执行上下文
            /*
                js每段代码的执行都会存在于一个执行上下文环境中,而任何一个执行上下文环境会存在于整体的执行上下文中。
                根据栈先进后出的特点,全局环境产生的执行上下文环境会先压入栈中,存在于栈底。
                当新的函数进行调用时,会产生的新的执行上下文环境,也会压入栈中。
                当函数调用完成后,这个上下文环境及其中的数据都会被销毁,并弹出栈中,从而进入之前的执行上下文中。
                处于活跃状态的执行上下文环境只能同时有一个。
            */

            var a= 10;              //1.进入全局执行上下文环境(全活)
            var fn = function (x) {
                var c = 10;
                console.log(c+x);
            };
            var bar = function (y) {
                var b = 5;
                fn (y+ b);         //3.进入fun()函数执行上下文环境(fn()活)
            };
            bar (20);               //2.进入bar()函数执行上下文环境(bar()活)
        
        //2.闭包
            /*
                函数拥有的外部变量的引用,在函数返回时,该变量仍然处于活跃状态。
                在js中存在一种内部函数,即函数声明和函数表达式可以位于另一个函数的函数体内,
                在函数中就可以访问外部函数声明的变量,当这个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

                消耗内存
            */
                                        //1.进入全局执行上下文环境
           function fn1 (){               
               var max = 10 ;
               return function bar (x){ //3.进入bar (x)执行上下文环境
                   if(x>max){           //调用maxbar()不会被销毁
                       console.log(x);
                   }
               };
           };
           var fl=fn1();
           fl(11);                      //2.进入fn (x)执行上下文环境

        //3.闭包用途
            // 3.1计数器
            /*
                通过自调用函数add实现闭包
                
            */
                var add = (function () {
                    var counter = 0;
                    return function () {return counter += 1;}
                })();

                add();
                add();
                add();
            //3.2结果缓存
            /*
                缓存一些数值
            */
                var cachedBox = (
                    function(){
                        //缓存的容器
                        var cache={};
                        return{
                            searchBox:function(id){
                                //如果再内存中,则直接返回
                                if(id in cache){
                                    return '查找结果为:'+cache[id];
                                }
                                //经过一段时间的dealFn函数处理
                                var result = dealFn(id);
                                //更新缓存的结果
                                cache[id]=result;
                                //返回计算的结果
                                return '查找的结果为:'+result;
                            }
                        };
                    }
                )();
                //处理很耗时函数
                function dealFn(id){
                    console.log('这是一段很耗时的操作');
                    return id;
                }
                //两次调用
                console.log(cachedBox.searchBox(1));
                console.log(cachedBox.searchBox(1));
    </script>
</body>
</html>

  

posted @ 2021-09-08 18:01  飞渝  阅读(92)  评论(0)    收藏  举报