闭包应用

Posted foreverwaiting

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了闭包应用相关的知识,希望对你有一定的参考价值。

1.闭包含义

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>闭包就是一个对象,里面包含着一个函数,以及包含着一个被它捕获的变量</p>
    <script>
        function f1(){
            var a=1;
            var b=2;
            function f2(){//此时已经产生闭包了。f2的【scope】-->f1的词法环境(Lx)
                console.log(a);
            }
            f2();
        }
        f1();
    </script>
</body>
</html>

 

2.闭包应用之减少全局变量

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>闭包好处一:减少全局变量</p>
    <script>
        //1.有时当我们需要实现一个函数每调用一次都自增的效果,但是根据局部变量的垃圾回收机制,这个例子显然不能实现
//        function f(){
//            var a=1;
//            a++;
//            alert(a);
//        }
//        f();
//        f();
//        f();
        //2.于是我们把a设为全局变量,虽然效果实现了但是会导致全局变量过多,在大型项目中会产生命名冲突等一系列问题
//        var a=1;
//        function f(){
//            a++;
//            alert(a);
//        }
//        f();
//        f();
//        f();
        //3.而闭包却能解决这个问题,
        function f(){
            var a=1;
            return function(){
                a++;
                alert(a);
            }
        }
        var g=f();
        g();
        g();
        g();
        //至此,我们使用闭包解决了这个问题,由于局部变量在子函数中被引用,而使其不能被垃圾回收机制回收,并且由于子函数可以引用该变量,所以return子函数,就能在函数外部引用该变量了。只要不关闭浏览器不关闭该页面,函数外部就可以引用,这样的话a就不会被回收,值也就可以保存,也就可以递增
    //但是需要注意一个问题,闭包的存在会使得它不会被垃圾回收机制回收,它就会比其他函数占更多的内存,如果过渡使用闭包可能会导致内存占用过多。可能会导致浏览器崩溃的问题。那么解决的方法就是当已经达到我们需要达到的效果时,应该解除对匿名函数的引用,没有了引用,就变成了普通函数,就会被垃圾回收机制回收。
    </script>
</body>
</html>

 

3.闭包应用之减少减少传递给函数的参数的数量

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>好处二:减少传递给函数的参数的数量</p>
    <script>
        //实现下面这个例子需要两个参数,a为基数,b为在i自增后的和
//        function f(a,b){
//            var c;
//            var d=0;
//            for (var i=1;i<=b;i++){
//                d+=i;
//            }
//            c=a+d;
//            alert(c);
//        }
//        f(3,4);//弹出结果为3+(1+2+3+4)=13
        //下面这个例子采用闭包可以用一个参数实现同样的效果
        function f(a){//创建基础值函数,参数为a。(f函数其实相当于一个创建函数的工厂一样,它返回另外一个即其内部的函数)
            return function(b){//创建自增加函数并返回(这个函数作为其内部函数会引用其参数形成闭包)
                var c=0;
                for(var i=0;i<=b;i++){
                   c+=i;//for循环实现自增到参数b,并赋值给c
                }
                return c+a;//返回c与基础值的和
            }
        }
        var g=f(2);//将f()函数赋值给g,给f函数传入参数2,即基础值2.(其实就是把f函数的返回值即自增加函数赋值给g,说白了,单看f()函数时,就是f()函数,当把f()函数当作值赋值时,f()函数的值其实就是其内部return的函数)
        alert(g(3));
        alert(g(4));//此时弹出g函数,给g函数传入参数3,也就是给f函数的返回值即自增加函数传入参数3.
        //最终弹出结果为2+(1+2+3)=8. 2+(1+2+3+4)=12.
        var g1=f(3);//当然也调用多次f()函数赋值,每调用一次,改变一次基础值函数的参数值,产生一个新的闭包
        alert(g1(4));
        alert(g1(5));//结果为3+(1+2+3+4)=13. 3+(1+2+3+4+5)=18.
    </script>
</body>
</html>

 

4.闭包应用之封装

 

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <p>好处三:封装</p>
    <script>
        (function(){
             var m=0;
             function getM(){//得到m值
                 return m;
             }
             function setM(val){//设置m值
                 m=val;
             }
             window.g=getM;//为了在外部访问到,将其公布出函数外。
             window.s=setM;
         })();//自调用函数,将其封装
        s(10);//设置值为10
        alert(g());//得到弹出值为10
    </script>
</body>
</html>

 

以上是关于闭包应用的主要内容,如果未能解决你的问题,请参考以下文章

JS---闭包

scala编程——函数和闭包

JS之闭包的应用

javascript 匿名函数及闭包----转载

Swift之“闭包”的应用

JavaScript闭包应用场合——控制前端接口轮训