一、定义
一句话概括闭包:能够访问函数内部变量的函数与这个变量的组合构成了闭包结构。如下代码
function fuc1(){
let num = 999
return function fuc2(){
console.log(num)
}
}
fuc1()();
如代码所示,fuc2和父级变量num构成了一个闭包环境。
二、原理
子函数引用了父函数中的变量,导致父函数中的变量不能被垃圾回收机制清除。
三、应用场景
1、变量私有化,防止变量被污染。
var Counter = (function () {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function () {
changeBy(1);
},
decrement: function () {
changeBy(-1);
},
value: function () {
return privateCounter;
},
};
})();
console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */
另外vue中data就是应用了闭包来实现各个组件数据私有化的,避免了组件之间的数据互相影响。
2、函数防抖
let inp = document.querySelector("input")
function fun() {
console.log(this.value)
}
inp.oninput = debounce(fun, 3000)
function debounce(fun,delay) {
let t = null
console.log('闭包父级变量T---->',t)
return function () {
console.log(t,"----每次触发input事件,t的值")
if (t) {
console.log(t,"清除定时器的值")
clearTimeout(t) //每一次触发事件都要先清除定时器然后再重新设置定时器
}
t = setTimeout(() => {
fun.call(this)
console.log(t,"setTimeout内")
}, delay);
}
}
3、延长生命周期。
函数内部的变量被外部引用,那么它就不会被清理掉,一直存在于内存中。
四、缺点
父级函数的变量会永久存放在内存中,除非手动清除,否则容易造成内存泄露。