闭包
函数作为返回值
高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。
我们来实现一个对Array的求和。但是,如果不需要立刻求和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求和的函数!
function lazySum(arr) {
return function () {
return arr.reduce(function (x, y) {
return x+y;
})
}
}
调用函数f时,才真正计算求和的结果:
let f = lazySum([1, 2, 3, 4, 5]); // function sum()
请再注意一点,当我们调用lazySum()时,每次调用都会返回一个新的函数,即使传入相同的参数:
let f1= lazySum([1,2,3,4,5]);
let f2 = lazySum([1,2,3,4,5]);
console.log(f1 === f2); //false
说了这么多,难道闭包就是为了返回一个函数然后延迟执行吗?
当然不是!闭包有非常强大的功能。举个栗子:
在面向对象的程序设计语言里,比如Java和C++,要在对象内部封装一个私有变量,可以用private修饰一个成员变量。
在没有class机制,只有函数的语言里,借助闭包,同样可以封装一个私有变量。我们用JavaScript创建一个计数器:
function create_counter(initial) {
let x = initial||0;
return {
increase(){
x += 1;
return x;
}
}
}
它用起来像这样:
var c1 = create_counter();
c1.increase(); // 1
c1.increase(); // 2
c1.increase(); // 3
var c2 = create_counter(10);
c2.increase(); // 11
c2.increase(); // 12
c2.increase(); // 13