**闭包会造成内存泄漏吗? (Closure)


    结论:** 闭包不会造成内存泄漏。

    闭包:表示一种函数,是一种带有执行环境的函数。

    执行环境
    1. 函数的词法环境(this作用域);
    2. 表示符列表(用到但未声明的变量);

    1. 表达式部分(函数体);

    下面的例子1中:访问变量a,是通过作用域链的方式找到a,并不是闭包,只是闭包的现象。

    1. var a = 1;
    2. function fn() {
    3. console.log(a); //访问未声明的变量
    4. }
    5. fn();

    例子2:闭包,并不是通过作用域链去寻找,而是通过闭包去寻找。

    1. var a = 3;
    2. function fn() {
    3. var a = 2;
    4. return function() { //此函数带有执行环境
    5. console.log(a); //闭包
    6. };
    7. }
    8. fn()(); //this => window

    Note:如果fn里没有定于变量a,则输出3,很像作用域链,过于灵活,没有边界。

    内存泄漏:
    内存泄漏(Memory Leak)是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。
    -> 阻止额外的,或可避免的花销(内存占用)。
    闭包会不会因为内存泄漏 - 图1
    早期IE浏览器垃圾回收机制(引用计数**策略**)不能回收掉闭包中未声明的变量。如果是循环引用,则回收不了,是早期IE的bug。

    例子:循环引用。

    1. var o = {};
    2. var o2 = {};
    3. o.a = o2;
    4. o2.a = o;

    所以,就有了闭包会引起内存泄漏的说法。

    目前的浏览器不在使用引用计数策略的垃圾回收机制,而是使用 标记清除 垃圾回收算法。(在引用计数基础上增加了根对象,进行了优化。)
    此算法增加了 (root )根对象,一定周期内会去查看是否能访问到root.o,和root.o2。

    内存溢出
    内存溢出(out of memory)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于虚拟机能提供的最大内存。此时程序就运行不了,系统会提示内存溢出,有时候会自动关闭软件,重启电脑或者软件后释放掉一部分内存又可以正常运行该软件。

    内存泄漏不会报异常,内存溢出则一定会报异常。