//有一个 a 函数functiona(){var num =100//a 函数内部返回一个 b 函数returnfunctionb(){//b 函数内部访问着 a 函数内部的私有变量
console.log(num)}}//a 函数外部有变量引用 这个 b 函数var res =a()//这里的res实际上就是a函数的return返回值 b函数
了解闭包,需要先了解函数的两个阶段
一、定义阶段
开辟一个 存储空间
把和函数体内的代码一模一样的字符串放在这个空间内(不解析变量)
把 存储空间 的地址给函数名
二、调用阶段
按照函数名的地址找到函数的 存储空间
形参赋值
预解析 (var的声明提升)
将函数 存储空间 中的代码拿出来执行(这个时候才解析变量)
在函数的调用阶段,会在内存中开辟一个执行空间,而在函数执行完毕后,执行空间立即销毁。
按照函数名的地址找到函数的 存储空间
形参赋值
预解析
在内存中开辟一个 执行空间
将函数 存储空间 中的代码拿出来在刚刚开辟的 执行空间 中执行
执行完毕后,内存中开辟的 执行空间 销毁**
函数的执行空间
functionfn(){
console.log('这是一个函数')}fn()
函数定义的时候会有一个存储空间(将其命名为xxff00),一直存在
函数执行的时候会开辟一个 执行空间(将其命名为 xxff11)
console.log('我是 fn 函数')这个代码就是在 xxff11 这个空间中执行
代码执行完毕以后,这个 xxff11 空间就销毁了 -
不销毁的函数执行空间
每一个函数都会有一个 存储空间
但是每一次调用都会生成一个完全不一样的 执行空间
并且 执行空间 会在函数执行完毕后就销毁了,但是 存储空间 不会
那么这个函数空间执行完毕就销毁了,还有什么意义呢?
我们可以有一些办法让这个空间 不销毁
闭包,就是要利用这个 不销毁的执行空间,并且我们将这个不销毁的函数执行空间叫做 闭包空间
functiona(){// 这个 num 变量就是函数 a 的私有变量var num =100returnfunctionb(){
console.log(num)}}// res 接受的是 a 函数执行以后的返回值// res 接受的就是函数 a 内部返回的一个复杂数据类型(函数b)// 导致函数 a 的执行空间不会销毁var res =a()res()// 打印出来为 100// 从现在开始, res 随时可以是一个 函数a 里面返回的 函数b// res 随时可以调用// 当 res 调用的时候, 打印 num// 打印出来的就是 a 函数内部的私有变量 num 的值