百度百科中解释到:闭包就是能够读取其他函数内部变量的函数。
怎么理解闭包
从这句话我们可以得到两点:
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. 闭包特性就是能够访问到函数的局部变量。当我们将闭包函数作为一个对象来使用,局部变量当做私有属性来使用的时候,切记不要在外部改变这个局部变量,这会让程序达不到你的预期。
浅陋见识,不足之处,请大神指正。