一、什麼是閉包?
先說概念:
閉包是指有權訪問另一個函數作用域中變量的函數。
創建閉包的最常用的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。
二、關於閉包概念的理解
從概念中可以看出,要形成閉包有2個不可或缺的關鍵因素,分別是:
①1個函數 ②函數內部可以訪問的變量
比如:
var num = 665;
function sayAlert(){
alert(num);
}
(在上述例子中,num就是1個變量,而sayAlert則是一個函數,在該函數中可以訪問num這個變量。)
緊接着把這幾句代碼放到一個立即執行函數中,再return該函數,如下所示:
function say666() {
var num = 665;
function sayAlert() {
alert(num);
}
num++;
return sayAlert;
}
var sayAlert = say666();
sayAlert(); //執行結果爲彈出666
在上述例子中,sayAlert函數和num變量就形成了閉包。
可以看出有兩個問題:
一、爲什麼需要函數嵌套函數?
函數嵌套函數是爲了讓變量成爲局部變量,比如在上述例子中num就成爲了局部變量,如果不嵌套直接寫在外面就成爲了全局變量。
所以,函數套函數就是爲了製造出一個局部變量。
二、爲什麼需要return函數?
return函數就是爲了讓這個函數可以被使用,在上述例子中return sayAlert就是爲了讓這個函數在外部可以被使用。
解決了上述兩個問題後,又有一個問題出現了:
爲什麼要讓變量成爲局部變量呢?
我想這個問題有好幾個答案,首先是局部變量可以一直被保存在內存中,不會被垃圾回收機制回收。還有就是可以通過閉包來隱藏一個變量,比如在上述例子中我們也完全可以讓num成爲一個全局變量,但是我又不想讓num這個變量的值被任何人任意更改(不想讓別人直接訪問到這個變量),所以我們可以讓它成爲局部變量,並且暴露一個函數,讓他人可以間接訪問。
三、分享一個閉包使用案例
最後給大家分享一個閉包的使用案例,使用閉包讓 4個li節點的onclick事件都能正確的彈出當前被點擊的li索引:
<ul>
<li>index =0</li>
<li>index =1</li>
<li>index =2</li>
<li>index =3</li>
</ul>
<script>
var nodes=document.getElementsByTagName("li");
for(var i=0;i<nodes.length;i++){
nodes[i].οnclick=(function(i){
return function(){
console.log(i)
}
})(i)
}
</script>
在上述例子中,return後的函數和變量i就形成了閉包,如果不使用閉包直接打印的話,那麼不管點擊哪個li打印出來的值都是4。
大家可以自行嘗試。
有任何問題歡迎在留言區指出和討論(✿◕‿◕✿)