闭包的概念:
1.闭包是嵌套的内部函数
2.包含被引用变量(函数)的对象=>引用外部函数变量,延长外部函数变量的生命周期
闭包的作用
1. 延长外部函数变量对象的生命周期
2. 让函数外部可以操作(读写)到函数内部的数据(变量/函数)
3. 注意: 浏览器为了性能后期将外部函数中不被内部函数使用的变量清除了
function fn1(){
var a = 0;
var b = 100;
function fn2(){
a++;
console.log(a);
}
return fn2;
}
var f = fn1();
f(); //1
f(); //2
var f1 = fn1();
f1(); //1
f1(); //2
应用场景1:防抖
//获取元素
const input = document.getElementById('input')
//靠定时器实现防抖(笨、不好看)
let timeId=''
input.onkeyup = (event)=>{
//外部函数清除内部内部函数的定时器函数
if(timeId) clearTimeout(timeId)
timeId = setTimeout(()=>{
console.log('timeId没内容输出')
},200)
}
防抖应用的其实就是闭包,外部函数嵌套内部函数(settimeout),并且定时器引用了外部变量(timeId),延长了外部变量的声明周期,如果外部变量不使用,那就会被js的垃圾循环机制清除,利用闭包可以一直引用外部的变量。
优点:延长timeId生命周期(可以不被垃圾回收机制清除啦)
缺点:闭包耗费性能,容易造成内存泄露
那么如何避免内存泄露,在不使用闭包时,把被引用的变量设置为null,即手动清除变量,这样下次js垃圾回收机制回收时,就会把设为null的量给回收了。上面这个防抖就是通过clearTimeout清除。
应用场景2:管理系统中的删除某一项
在后台管理系统中我们通常会写到点击某一项对他进行删除操作,通过点击删除按钮触发回调,这个回调中需要向服务器发送删除请求,这个时候实现了函数嵌套函数,并且我们删除某一项内容的时候需要传递一个标识(比如id),那么这个id就是外部变量,对这个id实现了延长生命周期的作用,此时也就形成了闭包。