什麼是閉包?
閉包一般人都說, 是函式中定義的乙個函式,有的人也說函式中套函式。
其實準確點說,閉包是乙個能夠訪問到其他函式內部變數的函式,
當然這個其他函式不是父子關係的函式, 而是兄弟關係的函式。
舉個最簡單的例子引導一下
functionalwayslinger()
console.log( num ); //
num is not defined;
在外面訪問 num 肯定是訪問不到,還會報錯:num is not defined;
但是你又想訪問到 alwayslinger 函式內部的區域性變數。
這是時候你就需要閉包了。
functionalwayslinger()
}console.log(
alwayslinger()());
//0;
看起來,好像也沒有什麼神奇之處,當你呼叫alwayslinger函式後,返回乙個函式,執行返回的函式,再次返回 num 變數。
這樣就取了函式內部的值。看到這裡你可能你會迷惑, 為什麼要返回乙個函式,然後再返回num呢,直接返回num不好嗎?
我建議你帶著這個疑問看下去。
閉包其實是一種現象:
父函式內的子函式,被父函式之外的變數引用,父函式裡的變數永遠不會銷毀(也說明了js的垃圾**機制不會生效,父函式中的變數永遠存在)
下面舉幾個例子,簡單的說明閉包常見的運用場景。
1、使變數始終存在記憶體中
functionalwayslinger()
}console.log( alwayslinger()() ); //0
console.log( alwayslinger()() ); //
0console.log( alwayslinger()() ); //
0console.log( alwayslinger()() ); //
0var func =alwayslinger();
console.log( func() ); //1
console.log( func() ); //
2console.log( func() ); //
3console.log( func() ); //
4console.log( func() ); //
5
前幾個console,輸出同乙個值,是因為每次執行都返回乙個新值,
後幾個console,輸出遞增的值,是因為每次執行後操作的都是乙個值,就是函式中的區域性變數num。我們使用閉包不單單只是為了取到區域性變數,還要去操縱它。
2、模擬塊級作用域
比如,我們現在要實現點選列表,實現彈出列表的索引值。
//先獲取到列表項 li
var list = document.queryselectorall("li");
//遍歷 li
for (var i = 0; i < list.length; i++)
}
一起看起來,好像並沒有什麼毛病,但是執行的結果卻是不管點選那個都是返回最後乙個索引值。這是因為在es5中沒有塊級作用域的原因導致的, 解決的辦法很多種舉幾種常用的解決辦法。
1、閉包方式var list = document.queryselectorall("li");
for (var i = 0; i < list.length; i++)
})(i)
}//迴圈內部加乙個自執行函式,利用函式作用域,模擬塊級作用域。
2、利用let代替var宣告, 告訴瀏覽器使用es6語法
var list = document.queryselectorall("li");
for (let i = 0; i < list.length; i++)
}3、 使用foreach 迴圈
var list = document.queryselectorall("li");
list.foreach(
function
(item,i)
})2,3兩種方法跟今天沒有關係,這裡就不多做討論。
來乙個比較坑的面試題。
functioncreatefunction ()
} return
result;
}var afunction =createfunction ();
afunction.foreach(
function
(obj))
大家可以自己嘗試著猜猜,結果是什麼?
再來乙個差不多的面試題。
for (var i = 0; i < 10; i++) , 0);}
細心的小夥伴或許已經發現了,這種比較迷惑人的面試題,都有乙個共同的特徵,就是在迴圈中包含了乙個函式。只要遇到這種問題,都可以用閉包來解決。
3、代替全域性變數
我們都知道如果乙個程式全域性變數太多的話,會影響效能, 那麼怎麼解決呢,其實最根本的就是把全域性變數變成區域性變數;
(function() test();
/*..... 一堆堆邏輯 .....
*/})()
console.log(name)
//name not defined;
// 這樣的話,在外界就訪問不到變數了,避免了全域性變數的增多。---恢復內容結束---
# 閉包
以上就是我對閉包的理解,如果有錯誤的地方請提出,歡迎批評指正。一起學習一起進步。
再次認識閉包
1 官方一點說,能夠讀取其他函式內部的區域性變數的函式,即為閉包。抓住幾個點 2 從表現上來認識 乙個函式a裡定義了另乙個函式b,b讀取了a的區域性變數 3 從特性上去認識 函式內定義的區域性變數,會隨著函式的執行完畢而被銷毀,記憶體被 但是在閉包存在的情況下,區域性變數被閉包函式引用,因此沒有被立...
關於STRUCT的幾點認識
1.struct 的巨大作用 面對乙個人的大型 c c 程式時,只看其對struct 的使用情況我們就可以對其編寫者的程式設計經 驗進行評估。因為乙個大型的c c 程式,勢必要涉及一些 甚至大量 進行資料組合的結構體,這些結 構體可以將原本意義屬於乙個整體的資料組合在一起。從某種程度上來說,會不會用...
關於C C 的幾點認識
從學習c語言開始,已經接觸這門語言好幾年了,不敢說有多精通,本文就本人以往遇到過的幾個問題做乙個說明。1 認識c語言的安全隱患。首先,我們來看乙個簡單的例子。int ndata 50 char szbuf 20 memset szbuf,0,20 strcpy szbuf,const char nd...