一、什麼是匿名函數 創建一個函數並將它賦值給變數functionName,這種情況下創建的函數,即匿名函數。(函數表達式就是匿名函數) 二、閉包 1.什麼是閉包? 閉包就是能夠讀取其他函數內部變數的函數。 只有函數內部的子函數才能讀取局部變數,因此可以把閉包簡單理解成“定義在一個函數內部的函數”。 ...
一、什麼是匿名函數
創建一個函數並將它賦值給變數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函數的活動對象和全局變數對象(全家對象只有在網頁關閉時才會銷毀),這導致f2始終在記憶體中,而f2的存在依賴於f1,因此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.使用閉包代替全局變數
//全局變數,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
再如:
(function(){ var now = new Date(); if(now.getMonth() == 0 && now.getDate() == 1){ console.log("Happy new year!") } })();
2.函數外或在其他函數中訪問某一函數內部的參數
function test () { var num = 1; function other() { console.log(++num) } return other; } var result = test(); console.log(result()); //2 console.log(result()); //3
3.利用閉包模仿塊級作用域
(function(){
for(var i =0;i<5;i++){
console.log(i)
}
console.log(i); //5 //本身只是到4,但這個地方還是訪問到了,所有輸出了5
})();
console.log(i); //undefined //利用閉包後,便形成了塊級作用域,讓外面訪問不到了。