前端面試必問——JS中的閉包是什麼?

一、什麼是閉包?

先說概念:

閉包是指有權訪問另一個函數作用域中變量的函數。

創建閉包的最常用的方式就是在一個函數內創建另一個函數,通過另一個函數訪問這個函數的局部變量,利用閉包可以突破作用鏈域,將函數內部的變量和方法傳遞到外部。

 

二、關於閉包概念的理解

從概念中可以看出,要形成閉包有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。

大家可以自行嘗試。

 


有任何問題歡迎在留言區指出和討論(✿◕‿◕✿)

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