首先我们要知道
- 有全局变量和局部变量
- 环境存在的意义是是否需要 需要就会被保留
- 只有在全局环境会被保留 一般局部变量只会被使用一次 就会被回收
- 每调用一次函数 会新开一次地址(空间) 当然不被调用就不会开辟空间
那么闭包存在的意义就是 让局部变量不被回收 即让局部变量被需要 即把它放在全局中
什么是闭包
声明在一个函数中的函数,叫做闭包函数。
闭包是指有权访问另外一个函数作用域中的局部变量的函数。
而且内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后。
看下面例子 :
function fun() {
var n = 1;
function sum() {
n++;
console.log(n);
}
sum();
}
fun(); //不管调用几次 返回都是2
fun(); //2
fun(); //2
由于是局部变量 就相当于 sum() 只使用一次就废弃了
如果想让它持续被使用
这样写 :
function fun() {
var n = 1;
return function sum() {
n++;
console.log(n);
}
sum();
}
var newFun = fun();
newFun(); //2
newFun(); //3
newFun(); //4
这样 就可以实现重复使用sum() 即延长了其生命周期
为什么呢 可以这样理解 : 当返回的是里面sum()函数时 就把sum()放在了全局 调用 就可以重复被使用
从而实现了局部函数sum() 可以被重复使用
sum()
函数就是闭包函数
再看下面这个例子 :
function fun() {
var n = 1;
return function sum() {
n++;
console.log(n);
}
sum();
}
var newFun = fun();
var newnewFun = fun();
newFun(); //2
newFun(); //3
newFun(); //4
newnewFun(); //2
newnewFun(); //3
newnewFun(); //4
因为我们上面说过了 重新调用函数的时候会重新开辟空间
虽然 newFun() 和 newnewFun() 指向同一个函数, 但每调用一次函数会重新开辟一个新的空间
这样重新命名再调用 就相当于又调用原函数fun()
就类似重新开了一局游戏 这一局与上一局没一点关系
所以输出的值 二者毫不相干 又新开了一把而已
那么同样的道理 :
function fun() {
var n = 1;
return function show() {
return function sum() {
n++;
console.log(n);
}
}
}
var newFun = fun()();
newFun(); //2
newFun(); //3
newFun(); //4
同样的, 在构造函数中 :
function fun() {
var n = 1;
this.a = function() {
n++;
console.log(n);
}
}
var newFun = new fun();
newFun.a(); //2
newFun.a(); //3
newFun.a(); //4
var newnewFun = new fun();
newnewFun.a(); //2
newnewFun.a(); //3
newnewFun.a(); //4
闭包的用途:
- 可以读取函数内部的变量
- 让这些变量的值始终保持在内存中,不会在f1调用后被自动清除。(内存消耗很大,所以不能滥用闭包)
闭包的特点 :
1、让外部访问函数内部变量成为可能
2、局部变量会常驻在内存中
3、可以避免使用全局变量,防止全局变量污染
4、会造成内存泄漏(有一块内存空间被长期占用,而不被释放)
总结 : 闭包找到的是同一地址中父级函数中对应变量最终的值。
参考原文 : 什么是闭包 闭包的作用及用途