javascript 閉包詳解
阿新 • • 發佈:2018-11-30
一、什麼是匿名函式
建立一個函式並將它賦值給變數functionName,這種情況下建立的函式,即匿名函式。(函式表示式就是匿名函式)
二、閉包
1.什麼是閉包?
閉包就是能夠讀取其他函式內部變數的函式。
只有函式內部的子函式才能讀取區域性變數,因此可以把閉包簡單理解成“定義在一個函式內部的函式”。
我們只要把f2作為返回值,我們不就可以在f1外部讀取它的內部變量了嗎!
function f1 () { var num = 1; function f2() { console.log(num) } return f2; } var result = f1(); console.log(result()); //1
2、閉包的用途
閉包可以用在許多地方。它的最大用處有兩個,一個是前面提到的可以讀取函式內部的變數,另一個就是讓這些變數的值始終保持在記憶體中。
function f1 () { var num = 1; function f2() { console.log(++num) } return f2; } var result = f1(); console.log(result()); //2 console.log(result()); //3
原因就在於f1是f2的父函式,而f2的作用域綁上了f1函式的活動物件
3.使用閉包的注意點
1)由於閉包會使得函式中的變數都被儲存在記憶體中,記憶體消耗很大,所以不能濫用閉包,否則會造成網頁的效能問題,在IE中可能導致記憶體洩露。解決方法是,在退出函式之前,將不使用的區域性變數全部刪除。
2)閉包會在父函式外部,改變父函式內部變數的值。所以,如果你把父函式當作物件(object)使用,把閉包當作它的公用方法(Public Method),把內部變數當作它的私有屬性(private value),這時一定要小心,不要隨便改變父函式內部變數的值。
var name = "The Window"; var object = { name : "My Object", getNameFunc : function(){ return function(){ return this.name; }; } }; alert(object.getNameFunc()()); //The Window 匿名函式的執行環境具有全域性性,因此其this物件通常指向window。
4.閉包的應用場景
1.使用閉包代替全域性變數
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
//全域性變數,test1是全域性變數
var
test1=111;
function
outer(){
console.log(test1);
}
outer();
//111
console.log(test1);
//111
//閉包,test2是區域性變數,這是閉包的目的
//我們經常在小範圍使用全域性變數,這個時候就可以使用閉包來代替。
(
function
(){
var
test2=222;
function
test(){
console.log(
"測試閉包:"
+test2);
}
test();
//測試閉包:222
}
)();
console.log(test2);
//未定義,這裡就訪問不到test2 再如:
|
1 2 3 4 5 6 |
(
function
(){
var
now =
new
Date();
if
(now.getMonth() == 0 && now.getDate() == 1){
console.log(
"Happy new year!"
)
}
})();
|
2.函式外或在其他函式中訪問某一函式內部的引數
1 2 3 4 5 6 7 8 9 10 |
function
test () {
var
num = 1;
function
other() {
console.log(++num)
}
return
other;
}
var
result = test();
console.log(result());
//2
console.log(result());
//3
|
3.利用閉包模仿塊級作用域
1 2 3 4 5 6 7 |
(
function
(){
for
(
var
i =0;i<5;i++){
console.log(i)
}
console.log(i);
//5 //本身只是到4,但這個地方還是訪問到了,所有輸出了5
})();
console.log(i);
//undefined //利用閉包後,便形成了塊級作用域,讓外面訪問不到了。
|