闭包的定义
闭包包含自由(未绑定到特定对象)变量,这些变量不是在这个代码块内或者任何全局上下文中定义的,而是在定义代码块的环境中定义(局部变量)。 -----百度百科
在日常JavaScript的代码编写中闭包是非常普遍的,只不过这种使用方法太普通了,我们并没有注意到。如果java程序员转的JavaScript一定会惊叹这种强大灵活的特性。
闭包例子
我们需要写一个函数,它能够生成累加器,即这个函数接受一个参数a,然后返回另一个函数,后者接受参数b,然后返回a增加了b后的值。
function makeAdder(a) {
return function(b) {
return a + b;
};
}
var add5 = makeAdder(5);
var add20 = makeAdder(20);
add5(6); // ?
add20(7); // ?
在这个例子在执行了makeAdder(5)后a并没有被释放,而是被保存了下来,再次调用add5(6)时仍然可以访问a。
为什么会这样呢? 原因就在于makeAdder是匿名函数的的父函数,而匿名函数被赋给了一个全局变量,这导致匿名函数始终在内存中,而匿名函数的存在依赖于makeAdder,因此makeAdder也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。
闭包释放
闭包的大量使用会造成性能问题,幸好有一个比较简单的方式可以处理闭包问题。
我们把闭包赋值给一个变量,在闭包用完后吧这个变量指向null。
let makeAdder = function(a) {
return function(b) {
return a + b;
};
}
var add5 = makeAdder(5);
var add20 = makeAdder(20);
add5(6); // ?
add20(7); // ?
makeAdder = null