深入理解 JavaScript 閉包

第一部分:初遇閉包

http://www.runoob.com/js/js-function-closures.html

什麼是閉包?閉包有什麼作用?這是我遇到閉包時的第一反應。

閉包在JavaScript高級程序設計(第3版)中是這樣描述:閉包是指有權訪問另一個函數作用域中的變量的函數。

那麼閉包的作用也就很明顯了。

  1. 可以在函數的外部訪問到函數內部的局部變量。

  2. 讓這些變量始終保存在內存中,不會隨着函數的結束而自動銷燬。

在上面的代碼中,閉包指的就是function () {return counter += 1;}這個函數。首先解釋一下這段代碼,在變量add被賦值之前,第一個function執行了一次(執行且僅會執行一次),因爲這是一個函數表達式聲明方式並且聲明後加上了(),所以會自動執行一次。執行後add被賦值(匿名函數)了,add= function () {return counter += 1;}。然後每次調用add()函數時,返回的都是這個函數,因爲這個函數在第一個函數的內部,所以即使第一個函數執行完了,第二個函數依然能訪問counter(JS設計的作用域鏈,當前作用域能訪問上級的作用域)。

閉包是可以在另一個函數的外部訪問到其作用域中的變量的函數。而被訪問的變量可以和函數一同存在。即使另一個函數已經運行結束,導致創建變量的環境銷燬,也依然會存在,直到訪問變量的那個函數被銷燬。當然,如果僅僅是做一個簡單的計數器,大可不用這樣麻煩。下面這簡短的代碼就能輕鬆實現。

var a = 0;

function myFunction(){

a++;

document.getElementById("demo").innerHTML = a;

}

第二部分:牛客翻船

https://www.nowcoder.com/questionTerminal/da4115e308c948169a9a73e50d09a3e7

下面是這個題目的解答:

每個li標籤的onclick事件執行時,本身onclick綁定的function的作用域中沒有變量i,i爲undefined,則解析引擎會尋找父級作用域,發現父級作用域中有i,且for循環綁定事件結束後,i已經賦值爲4,所以每個li標籤的onclick事件執行時,alert的都是父作用域中的i,也就是4。這是作用域的問題。

閉包只能取得包含函數中任何變量的最後一個值。因爲別忘了閉包所保存的是整個變量對象,而不是某個特殊的變量。

這是在循環體中創建閉包的常見錯誤。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures(一定要看這篇

這裏面給onclick賦值的是閉包。很多人會問爲什麼是閉包?之前閉包不是函數A裏的函數B嗎?函數B用來訪問函數A的變量,稱函數B是閉包,題目中只有一個函數爲什麼也是閉包。其實,用兩個函數形成閉包只是一般形式。閉包真正的含義是,如果一個函數訪問了此函數的父級及父級以上的作用域變量,就可以稱這個函數是一個閉包。

var a = 1;

(function test (){

alert(a);

})()

所以上面的function都可以稱之爲閉包(匿名閉包函數)。

這裏還是作用域的問題,那麼我們把每次的i都保存到一個變量中,匿名閉包就可以實現想要的效果。

這樣就使用了閉包,這裏面的閉包指的是function() {alert(num);};第二個function裏面彈出的num是第一個function的參數,通過(i)執行了這裏面的第一個函數,同時i的值被保存到num中。每個點擊事件中都有一個局部變量num,num保存的是相應的i值。

第三部分:let的橫空出世

上面的牛客題目只需要將for(var i=0;ihttps://mp.csdn.net/postedit/81065540

let的到來,讓令人詬病的JS獲得了一絲生機,也補上了JS沒有塊級作用域的短板。ECMAScript6還有很多新特性,筆者也在不斷學習中。

第四部分:閉包的應用

函數工廠和閉包模擬私有方法

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures(這篇講得很好,希望大家讀透

這裏推薦一下我的前端學習交流q-u-n:731771211,裏面都是學習前端的從最基礎的HTML+CSS+JS【炫酷特效,遊戲,插件封裝,設計模式】到移動端HTML5的項目實戰的學習資料都有整理,送給每一位前端小夥伴。2019最新技術,與企業需求同步。好友都在裏面交流,每天都會有大牛定時講解前端技術!

點擊:加入

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