JS闭包

作者: 树袋熊熊 | 来源:发表于2016-09-30 14:33 被阅读0次

    javascript闭包 对我来说是一个难点,结合阮一峰老师,书籍以及同学的总结和建议写的这一篇笔记。在我看来 闭包 作用域 垃圾回收机制 函数嵌套 有关。

    首先闭包为什么会产生,他到底是解决什么问题?

    首先看一段代码:

    var n=2;

    function a (){

    alert(n);

    }

    a()         //此时返回2

    结果为什么是2呢?    ====>   n为全局变量

    再看一段代码:

    function a(){

    var n=2;

    }

    alert(n)      //error

    结果为什么是error呢?   ===>  n为局部变量

    这个是 变量作用域  的问题:变量作用域分为 全局变量  局部变量(对其的理解在作用域及作用域链中)

    那么你要读取函数的内部变量应该怎么解决?(1)

    这是一个问题!

    其次,看下面的代码:

    var n=2;

    function a (){

    alert(n);

    }

    a()         //此时返回2

    a()        //此时返回2

    为什么得到的结果不是下面这样呢?

    a()        //此时返回2

    a()        //此时返回3

    这个是javascript的垃圾回收机制问题:一个函数在执行开始的时候,会给其中的定义的变量划分内存空间保存,以备后面的语句所用,等到函数执行完毕后返回,这些变量就被认为是无用了,对应的内存空间就被回收了,再次执行时,所有的变量变为最初状态。

    那么想要本次的执行结果是继承在上次的执行结果的基础上的呢?(即想让该变量长期的保存在内存中应该如何解决?)(2)

    为了解决(1)(2)的两个问题所以引进了闭包。

    所以引出闭包的作用:一个是读取函数内部变量,另一个是让变量的值始终保存在内存中。

    既然闭包可以解决这两个问题,那么是怎样解决的呢?

    function  a(){

       var n="Mozilla";

       function displayName({

            alert(n);

    }

    return displayName;

    }

    var myFunc=a();

    myFunc();

    这里用到的是 函数嵌套 :函数内部又嵌套了另一个函数,而内部函数又使用了外部函数的某些变量,这是垃圾回收机制就会出现问题。

    此时javascript解释器在遇到函数定义的时候,会自动把函数和其他可能用到的变量一起保存起来,构成了闭包,只有当内部函数不被调用后,才销毁这个闭包。

    其实在写闭包的时候也可以用到匿名函数。===>匿名函数:无需定义函数名的函数或者子程序。看下面的代码助于理解:

    function a(){

        var n = 'rain-man';

        setTimeout(function(){ alert(n); } //这是一个匿名函数

    , 2000);

    }

    a();

    我用到的是ES6,所以上面的匿名函数就变为:

    setTimeout( ()=>{ alert(n); } //这是一个匿名函数 , 2000);

    当然闭包存在一些问题:

       一个是因为闭包使函数中变量都保存在内存中,内存消耗很大。

       另一个是在IE下可能导致内存泄露。(我理解的内存泄露是 页面跳转时变量不会释放,直到浏览器关闭才会释放。比较权威的解释是:一块被分配的内存,即不能使用,又不能被回收,直到浏览器进程结束)。

    如何去注意点这些问题:

    对于内存消耗大的问题,就要求我们不能滥用闭包,否则会造成网页的性能问题。

    对于IE下的内存泄露问题:退出函数前,将不使用的局部变量全部删除。主要使用window.onunload.具体可以参照js内存泄露问题


    闭包-知乎

    闭包-阮一峰

    相关文章

      网友评论

          本文标题:JS闭包

          本文链接:https://www.haomeiwen.com/subject/ydoxyttx.html