深入了解函数
在讲解闭包之前,我们先来了解函数。
函数在声明定义的时候,将函数的地址和函数名存储在栈中,在堆中开辟一个函数存储空间,将函数体以字符串形式存入
函数在调用阶段:按照函数名或者变量名找到堆中对应的储存空间,在堆中重新开辟一个函数执行空间,在这空间里进行函数赋值,预解析,把函数存储空间的代码复制到执行空间中执行,执行完后销毁
有了上面的知识,现在我们来学习js的闭包,就容易理解多了,好了,开始我们的js闭包学习
形成闭包的三个必要条件:
- 在一个函数A内部直接或者间接返回一个另一个函数B
- 返回的函数B内部要使用函数A的私有变量
- A函数外有一个变量接收着函数B,(接受的变量指向函数的执行空间,不能够销毁)如果不接收,直接在外面执行A(),执行完后函数执行空间会被销毁
闭包使用场景:
- 当你需要延长函数里变量的生命周期时使用
- 需要访问某一个函数内部的私有数据时,可以使用闭包
注意:如果有别的方法尽量不要使用闭包,因为闭包会形成一个不被销毁的空间,造成内存的浪费
下面写一个简单的例子了解一下闭包
画图解释上面的代码
可能看到这里,你已经对js闭包有了一定的理解,那就直接上一个面试题,检验一下
function fn(i){
return function(n){
console.log(n + (--i))
}
}
var f = fn(2)
f(3)
fn(4)(5)
fn(6)(7)
f(8)
我们可以画图解析一下上面的面试题
js闭包特点总结
js闭包的特点:(优点与缺点共存)
-
延长了变量的生命周期
优点:执行空间不被销毁,变量也没有销毁
缺点:变量一直在内存中,造成内存的消耗,可能会造成内存溢出问题 -
可以访问函数的内部的私有变量
优点:可以利用闭包函数访问函数内部的私有变量
缺点:变量一直在内存中,造成内存的消耗,可能会造成内存溢出问题 -
保护私有变量
优点:保护私有变量不会被外界访问
缺点:如果需要访问,必须利用闭包函数