经典的闭包代码
funciton foo(){
var name = 'akechi'
function bar(){
console.log("bar",name)
}
return bar
}
var fn = foo()
fn() //akechi
开始解析代码的执行步骤
-
首先初始全局执行上下文,编译foo函数和fn函数
-
开始执行代码 编译foo函数内部代码
-
执行foo函数的内部代码,返回bar函数对象的地址,赋值给fn函数

-
foo函数执行完毕,从ECStack挪出 (此时foo函数的ao对象没有被回收:因为bar函数父作用域指向它)
-
执行fn函数,即执行bar函数
MDN闭包的定义
闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合
🚧🚧在例子中的体现就是bar函数和它可以访问name变量
闭包为何会导致内存泄漏?
正常的函数的AO对象在函数执行完成被弹出ECStack,失去引用后会被GC回收
但是闭包的AO对象始终被作用域指向着,所以不会被回收
闭包的作用
在实际编码中,闭包通常用来保存一些数据,或应用在高阶函数、柯里化中 举个常用的JS防抖的🌰
/*timer和_debounce函数就形成了闭包*/
function debounce(fn,delay){
//1.定义一个定时器,保存上一次的定时器
let timer = null
//2.真正执行的函数
const _debounce = function(...args){
//取消上一次的定时器
if(timer) clearTimeout(timer)
timer = setTimeout(() => {
//外部传入的真正要执行的函数
//1.apply解决this指向问题 2.args解决event的传参问题
fn.apply(this,args)
},delay)
}
return _debounce
}