search
淺析JavaScript閉包,也許你會有不一樣的收穫

淺析JavaScript閉包,也許你會有不一樣的收穫

個人覺得閉包就扯到兩個問題:

一是關於函數作用域

二是關於函數最終值的問題

首先聊聊函數作用域

首先,JavaScript有函數作用域,但沒有像C#,Java,C++等語言一樣有塊級作用域的說法。

看看下面的函數 :

JavaScript沒有塊級作用域

對於web前端的學習有不懂的,或者不知道學習路線,不知道學習方法,不知道該如何紮實能找到工作的朋友,我還是要推薦下我自己建的前端學習群:477149581,首先你要是前端黨,其次不管你是小白還是大牛,我都挺歡迎,小白嘛,主動點多問問題也就學好了,群里每天分享乾貨,包括我自己最近花了一星期整理的一份適合2017年自學的最新web前端資料,送給大家,歡迎初學和進階中的小夥伴。

回顧一下,undefined出現的原因大多都是一個變數聲明了但是沒有賦值(如果變數沒有聲明會報錯的)。很明顯這樣就很好的解釋為什麼第一次輸出a是undefined了。其實上面這個函數等價於這樣書寫

輸出的結果也是一樣的

輸出結果也是一樣的,所以綜上所述:一個函數內聲明的變數在JavaScript引擎執行的時候都會把變數

提到最前面。所以說:

無論變數被塊級作用域內嵌的有多深,都會把變數提前

再來看閉包,W3C上是這樣定義閉包的:

閉包:指的是詞法表示包括不被計算的變數的函數,也就是說,函數可以使用函數之外定義的變數。

通俗的來說就是函數內部的函數可以訪問該函數的變數。

一般來說,一個函數只能訪問自己的內部(局部)變數和全局變數,不能訪問別的函數里的成員。

但是因為有閉包的存在使得函數內部的函數可以訪問該函數外部的變數。下面:

訪問c變數的時候報錯了

總結一下,一個函數能訪問的變數的原則是:從裡向外看,能看到的變數都可以訪問.

最後看看函數的最終值問題,也是應該特別注意的一點:

先看看下面的函數:

輸出10個10

首先定義一個Fun函數,在該函數裡面定義一個數組a,for循環為a數組添加一個函數。

所以返回的a數組裡面都是函數對象。然後用resule接收這個a數組,如果輸出resule[0]則是Function對象;resule[0]則是輸出i的值。也許你會以為會輸出0 1 2 3 4 ..但並不是這樣的。而輸出的都是10。所以可以看出,在JavaScript中函數聲明的地方向外看到的變數函數都能訪問,並且訪問的都是變數的最終值

如果我硬是要讓函數輸出0、1、2、3、4...挨著輸出怎麼實現呢?

看看下面的函數:

輸出0-9

上面的函數中,我們先要b函數接收每次傳來的i值,b函數執行了10次,每次的i值就這b函數的最終值了,所以這樣就可以輸出我們想要的效果了

閉包問題在JavaScript是一個難點,但閉包在JavaScript中是很有用的。

比如當我需要返回一個局部變數的時候可以在函數裡面內嵌一個函數返回;

看下面:

利用閉包訪問局部變數

閉包還可以實現私有成員,在這裡就不演示了。就說這麼多吧,改天再聊。

熱門推薦

本文由 一點資訊 提供 原文連結

一點資訊
寫了5860316篇文章,獲得23303次喜歡
留言回覆
回覆
精彩推薦