高階函數-->函數套函數,函數可以作爲另一個函數的參數。[同時一個函數的返回值也可以是個函數,這個就形成了閉包(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
說明:上面實現了一個計數器。這種用法是閉包比較重要的一個用法。有興趣的朋友可以比較這個用法和方法的差別嗎?可以的話可以評論回覆我一下哦。