函数作为返回值
普通的对数组的求和
function sum(arr) {
return arr.reduce(function (x, y) {
return x + y;
});
}
sum([1, 2, 3, 4, 5]); // 15
如果先不求和,到后面使用到时,再求和,可以这样:
function lazy_sum(arr) {
var sum = function () {
return arr.reduce(function (x, y) {
return x + y;
});
}
return sum;
}
调用时
var f = lazy_sum([1, 2, 3, 4, 5]); // function sum() 将f赋值为lazy_sum函数
//里面定义的一个函数名 sum
f();//15 真正调用f()时,才进行计算.
相关参数和变量都保存在返回的函数中,这种称为“闭包(Closure)”的程序结构
当我们调用lazy_sum()时,每次调用都会返回一个新的函数,即使传入相同的参数
闭包
理解 返回的函数并没有立刻执行
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push(function () {
return i * i;
});
}
return arr;
}
var results = count();
var f1 = results[0];
var f2 = results[1];
var f3 = results[2];
// 调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:
f1(); // 16
f2(); // 16
f3(); // 16
//全部都是16
//因为函数不是立刻返回的,而且,返回的是 return i * i;
//返回时,i的值已经是4了,所以 答案就是16
返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
如果一定要用,就再引入函数,使其绑定当前循环变量的值,略过.
闭包不仅仅为了返回一个函数然后延迟执行
封装私有变量:
'use strict';
function create_counter(initial) {
var x = initial || 0;
return {
inc: function () {
x += 1;
return x;
}
}
}
//这样用
var c1 = create_counter();
c1.inc(); // 1
c1.inc(); // 2
c1.inc(); // 3
var c2 = create_counter(10);
c2.inc(); // 11
c2.inc(); // 12
c2.inc(); // 13
在返回的对象中,实现了一个闭包,该闭包携带了局部变量x,并且,从外部代码根本无法访问到变量x。换句话说,闭包就是携带状态的函数,并且它的状态可以完全对外隐藏起来。
闭包创建新的函数pow2和pow3:
'use strict';
function make_pow(n) {
return function (x) {
return Math.pow(x, n);
}
}
// 创建两个新函数:
var pow2 = make_pow(2);
var pow3 = make_pow(3);
console.log(pow2(5)); // 25
console.log(pow3(7)); // 343