javascript中的闭包

百度百科中解释到:闭包就是能够读取其他函数内部变量的函数。

怎么理解闭包

从这句话我们可以得到两点:

1. 闭包是一个函数;

2. 通过这个函数我们可以获取其他函数的内部变量。

前面我们已经了解过作用域和作用域链的概念。我们了解到,内部函数可以通过作用域链访问到外部函数的局部变量。请看代码

function f1() {
    let i = 0;

    function f2() {
        console.log(i); //0
    }
}

在f2中,我们可以通过“作用域链”找到f1中的局部变量i。如果我们将f2作为一个返回值进行返回,在外部调用f2,是不是就可以在外部实现对内部函数的局部变量的调用。下面我们再看代码。

function f1() {
    let i = 0;

    function f2() {
        console.log(++i); 
    }

    return f2;
}

let fn2 = f1();
fn2(); //1
fn2(); //2

闭包的用途与作用

闭包作用主要有两个方面:

1. 访问内部函数的局部变量;

2. 将变量保存在内存中。

平时在工作中主要应用在第二个用途:将变量保存在内存中。

例如防抖函数实现中,对定时器变量的存储:

function f1(fn, wait) {
    let timer = null;
   let context = null;

    return function f2() {
        context = this;
        !timer && fn(context, ...arguments);

        if (timer) {
            clearTimeout(timer);
            timer = null;
        }

        timer = setTimeout(() => {
            clearTimeout(timer);
            timer = null;
        }, wait);
    }
}

let fn = f1(() => {}, 2000);

为什么timer这个局部变量不会被销毁。是因为f2被赋值给了一个全局变量,并且f2调用了f1的局部变量,所以造成f1也不会被销毁。

使用注意

1. 上面讲到闭包可以将变量保存在内存中,虽然这个特性比较强大,不过过多的滥用必将对浏览器带来负荷,所以在使用闭包之后,要对这些全局变量进行删除,达到释放内存的目的。

2. 闭包特性就是能够访问到函数的局部变量。当我们将闭包函数作为一个对象来使用,局部变量当做私有属性来使用的时候,切记不要在外部改变这个局部变量,这会让程序达不到你的预期。

浅陋见识,不足之处,请大神指正。

原文地址:https://www.cnblogs.com/heshuaiblog/p/14070551.html