JS闭包
前言
闭包是JS很强大的功能,但是也会很轻易把人搞晕。
下面运行完的结果是什么?
function makeAdder(a) {
return function(b) {
return a + b;
};
}
var add5 = makeAdder(5);
var add20 = makeAdder(20);
add5(6); // ?
add20(7); // ?
看起来 makeAdder 函数执行完后,它的局部变量就不存在了,错,它的局部变量依然存在。
第一个 makeAdder 的局部变量是 5 ,第二个 makeAdder 的局部变量是 20。
add5(6); // returns 11
add20(7); // returns 27
一、闭包 scope
任意时候JS执行一个函数时,都会创建一个 scope 对象,持有创建该函数的局部变量。
最开始 scope 使用函数参数变量进行初始化。
注意:
1、是每一次执行函数都创建 scope 对象。
2、scope 对象不能使用 js 代码直接访问。
针对前言中的示例:
1、makeAdder 创建了一个 scope 对象,持有参数变量a, {a:5}
2、makeAdder 返回了一个创建的函数。
一般情况下,JS垃圾回收器会在这时回收 scope 对象。
但是return 出来了函数对象持有着 scope 对象的引用,所以 scope 对象不会被回收。
3、直到 return 出来的函数对象不再被引用时,scope 对象才会被回收。
scope 对象形成了一个链,叫做 “scope 链”,类似于原型链。
闭包是由一个函数和它创建的 scope 对象所组成的。它可以保存状态,所以它可以用在对象所用的地方。