高阶函数-->函数套函数,函数可以作为另一个函数的参数。[同时一个函数的返回值也可以是个函数,这个就形成了闭包(Closure)]
函数作为返回值,这让我想到的了iOS开发中的Block,有兴趣的朋友可以好好比较一下。
eg1:
function sum(arr) {
var sum = function () {//在sum()函数内部定义了新函数
return arr. reduce(function (x,y){
return x + y;//新函数引用了sum的局部变量,并保存起来
});
}
return sum;
}
var sum1 = sum([1,2,3]);
var sum2 = sum([1,2,3]);
sum1();//6
sum1 === sum2;//false
说明:上面这个例子,sum()函数返回了一个函数,所以当只有执行sum1()的时候才会得到求和结果。并且sum1 === sum2结果为false,说明他们是相互独立的,就好像OC里面用同一个类创建两个对象,但是他们是不同的对象一样。
eg2:
function fun() {
var arr = [];
for (var i = 1;i <= 3;i ++){
arr.push(function (){//数组里面push进去的是函数
return i*i;//for的每次循环都会创建一个函数放进arr里面
});
}
return arr;//返回结果的时候,数组里面的每个元素都是i*i,此时i=4;
}
var answer = count();
var f1 = answer[0];//执行函数f1() = 16
var f2 = answer[1];//f2() = 16
var f3 = answer[2];//f3() = 16
说明:返回函数(就是push的参数)引用了fun的局部变量i,并且保存起来了,但是等到fun执行完了后i已经变为4了。得到的新数组里面的每一个函数都保存了i。
所以结果就是16。所以这里告诉我们,返回函数不要引用会发生变化的变量,如循环变量。相比eg1,eg2就是引用了变化的变量。
eg3:
(function (x) {
return x*x;
})(2);
说明:创建一个
匿名函数并
立即执行语法。
function count() {
var arr = [];
for (var i=1; i<=3; i++) {
arr.push((function (n) {
return function () {
return n * n;
}
})(i));
}
return arr;
}
var results = count();
var f1 = results[0];//执行f1() = 1
var f2 = results[1];//f2() = 4
var f3 = results[2];//f3() = 9
说明:相比eg2,eg3把每次的i绑定在了一个新函数里面。所以每次执行循环执行,把当时的i绑定在了匿名函数里面。
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
eg4:
function count(num) {
var x = num || 0;
return {//返回一个对象
privateProperty : function () {
x += 1;
return x;
}
}
}
var m1 = count();//0
m1.privateProperty();//1
m1.privateProperty();//2
var m2 = count(2);//2
m2.privateProperty();//3
m2.privateProperty();//4
说明:上面实现了一个计数器。这种用法是闭包比较重要的一个用法。 有兴趣的朋友可以比较这个用法和方法的差别吗?可以的话可以评论回复我一下哦。