内部函数总是可以访问其外部函数中声明的变量,当通过调用一个外部函数返回一个内部函数后,即使该外部函数已经执行结束了,但是内部函数引用外部函数的变量依然保存在内存中,就把这些变量的集合称为闭包。闭包中的数据会组成一个对象,然后保存在堆空间中。
// 当fn1函数执行完毕之后,其作用域是会被销毁的,然后垃圾回收器会释放那段内存空间。而闭包却很神奇的将fn1的作用域存活了下来,fn2依然持有该作用域的引用,这个引用就是闭包。由于返回的函数在其中引用了name的值,于是name的引用计数被+1。当返回函数不被垃圾回收时,则name也会一直存在。
function fn1() {
const name = 'dyx';
function fn2() {
console.log(name);
}
return fn2;
}
const fn3 = fn1();
fn3();
// 通过回调函数来进行函数值得传递
function fn1() {
const name = 'dyx';
function fn2() {
console.log(name);
}
fn3(fn2);
}
function fn3(fn) {
fn();
}
fn1();
闭包的应用
- debounce的闭包应用
handle变量在函数执行完之后并没有销毁,就是使用了闭包的原理。
const debounce = (fn, delay) => {
let handle = null;
return (...rest) => {
if (handle) {
// 取消之前的延时调用
clearTimeout(handle);
}
handle = setTimeout(() => {
fn.apply(this, rest);
}, delay);
}
}