闭包
一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure)。
简单来说就是一个函数可以访问其他函数作用域的变量。
function once(fn){
let flag = false;
return function(){
//done不会被释放
if(!flag){
flag = true;
return fn.apply(this,arguments)
}
}
}
let pay = once(function(money){
console.log(`已支付${money}元`)
})
// 只会执行一次
pay(1)
pay(1)
闭包的本质:函数在执行的时候会放到一个执行栈上当函数执行完毕之后会从执行栈上移除,但是堆上的作用域成员因为被外部引用不能被释放,因此内部函数依然可以访问外部的成员。
弊端
//内存泄漏
<div dec="a">1</div>
<div dec="b">2</div>
//script
let divs = domcument.querySelectorAll("div")
divs.forEach(item => {
let desc = item.getAAttribute("desc")
item.addEventListener("click",()=>{
console.log(desc)
//每次都会存储item,导致内存冗余
console.log(item)
})
//手动释放内存
item = null
})
常用的闭包操作
//防抖(debounce)
/**
* @fn: function 需要防抖的函数
* @delay: number 毫秒
**/
function debounce(fn,delay){
let timer = null //借助闭包
return function() {
if(timer){
// 在定时的过程中出发相同的事件
clearTimeout(timer)
}
timer = setTimeout(fn,delay)
}
}