zoukankan      html  css  js  c++  java
  • javascript进阶系列专题:闭包(Closure)

    在javascript中,函数可看作是一种数据,可以赋值给变量,可以嵌套在另一个函数中。

    var fun = function(){
        console.log("平底斜");
    }
    function fun(){
        var n=10;
        function son(){
           n++;
        }
        son();
        console.log(n);
    }
    fun();  //11
    fun();  //11

    我们把上面第二段代码稍微修改下:

    var n=10;
    function fun(){
        function son(){
           n++;
        }
        son();
        console.log(n);
    }
    fun();  //11
    fun();  //12

    看出差别了吗,如果理解不了代码执行结果,请看上一篇博文,关于javascript作用域和作用域链的讲解。

    上面这段代码中变量n是全局变量,随时可能被重新赋值,而无需通过fun函数的调用。为了让变量n不受污染,或者说是减少全局变量的污染,我们需要把n放到函数中作为局部变量。

    function fun(){
        var n=10;
        function son(){
            n++;
            console.log(n);
        }
        son();
    }
    fun();  //11
    fun();  //11

    如果我们可以在全局中直接调用son函数,那么便可以达成想要的效果。son函数现在是作为局部变量存在,要想在全局中访问,一般有两种方法:

    一种是赋值给全局变量

    var a;
    function fun(){
        var n=10;
        a = function son(){
            n++;
            console.log(n);
        }
    }
    fun();  //son()
    a();  //11
    a();  //12

    另一种是使用return返回值

    function fun(){
        var n=10;
        return function son(){
            n++;
            console.log(n);
        }
    }
    var a=fun();
    a();  //11
    a();  //12

    上面的son()函数就是闭包,某种意义上所有函数都可以看作闭包。闭包就是可以访问外层函数作用域的变量的函数。

    var a;
    function fun(){
        var n=10;
        a = function son(){
            n++;
            console.log(n);
        }
        return a();
    }
    fun();  //11
    a();  //12
    a();  //13
    fun();  //11
    a();  //12
    a();  //13

    还是上面那段代码,我们稍微修改下,再看看执行结果,这是因为每次执行fun()函数时都会初始化变量n。

    闭包的好处是减少全局变量,避免全局污染,可以将局部变量保存在内存中。但这既是优点又是缺点,一段代码中如果闭包过多,有可能造成内存泄露。由于闭包中局部变量不会被垃圾回收机制回收,所以需要手动赋值为null(关于内存泄露,后期单独开专题)

  • 相关阅读:
    使用 Apache OpenJPA 开发 EJB 3.0 应用,第 3 部分: 实体继承
    使用 Apache OpenJPA 开发 EJB 3.0 应用,第 2 部分: 开发第一个 Open JPA 应用
    使用 Apache OpenJPA 开发 EJB 3.0 应用,第 6 部分: 处理实体生命周期事件的回调
    http://www.oschina.net/question/129540_20547
    tomcat6实现远程调试
    FluorineFx和Flex配置
    今天才开通这个博客呀!
    vue中install方法
    Vue.nextTick 的原理和用途
    vue3.0中使用nextTick
  • 原文地址:https://www.cnblogs.com/newgold/p/5087203.html
Copyright © 2011-2022 走看看