JavaScript--閉包

高階函數-->函數套函數,函數可以作爲另一個函數的參數。[同時一個函數的返回值也可以是個函數,這個就形成了閉包(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

說明:上面實現了一個計數器。這種用法是閉包比較重要的一個用法。有興趣的朋友可以比較這個用法和方法的差別嗎?可以的話可以評論回覆我一下哦





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章