闭包的特征:其相关的局部变量在函数调用结束之后将会继续存在。
闭包的前提条件是需要在函数声明的内部声明另一个函数(即嵌套函数的声明)。
例1:
function f() {
var cnt = 0;
return function() {
return ++cnt;
}
}
从上面的示例可以看出,在调用函数fn时,其输出结果每次都会增加1,函数内的局部变量cnt在函数f的调用之后依然有效。
例2:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script>
function a() {
var aa = 123
function b() {
var bb = 234
console.log(aa)
}
return b
}
var obj = a()
obj()
</script>
</body>
</html>
看一下它的作用域链:
b函数被保存到外部执行,即使a函数执行之后断开了作用域链,但b定义时依然可以得到a函数的AO和GO,这就是产生闭包的原因。
所以说console.log(aa),输出是123。
注:这是因为引用的变量还存在,对象就不会成为垃圾回收机制的目标。aa在函数b中任然被使用,所以即使a函数执行完毕,aa也还存在在内存中。虽然闭包会保持对象,但无法保持call对象的属性所引用的之前的对象的状态,因为Call对象会在每次函数调用时被独立生成。