js闭包(closure)

闭包是什么?是用来做什么的?

Posted by AllocatorXy on February 15, 2017

js闭包(closure)

闭包原理:js中,子函数可以访问父函数的局部变量。

闭包是什么?

在函数内部再声明一个函数,调用父函数的局部变量,就形成了闭包。

function fn() {
    let i = 0;

    (function fn1() { // <= fn1就是闭包
        console.log(i); // console: 0
    })();
}

fn的变量i,对于fn1来说是可见的,所以fn1访问到了i;
fn1就是一个闭包


闭包的作用

闭包最常用的场合,就是读取函数的内部变量,并且让这些变量的值始终保存在内存中,而不与其他全局变量冲突,我们可以用它做某个函数内部变量的setter或getter;

function fn() {
    let i = 0;

    function fn1() { // <= 闭包fn1
        i++;
        console.log(i);
    }
    return fn1;      // 返回闭包fn1
}
let res = fn(); // res <= fn1
res();          // console: 1
res();          // console: 2
res();          // console: 3

可以发现,虽然ifn的局部变量,但它并没有在内存中被回收,而是一直存在于内存中的,
连续执行了三次闭包,如果它被回收了,那么结果应该是三次1,
但结果是i做了累加,说明i没有被销毁。
这是为什么呢?
闭包被赋给了一个全局变量res,这导致闭包fn1一直被存在内存中,而fn1的存在依赖于父函数fn,所以fn每次执行后并没有被销毁,i也就没有被销毁。


!!attention!!

由于闭包会使父函数中的局部变量一直保存在内存中,内存消耗是相当大的,所以不要大量使用闭包,否则会有严重的性能问题,在IE中可能导致内存泄漏;
应在退出函数前,将不要的局部变量删除
或在使用完闭包后,将储存闭包的变量删除