在面試題中,閉包應該是必問的問題吧(以下內容純屬個人理解,歡迎大家指正不足) 下麵我們就簡單的瞭解一下閉包這個東西到底是什麼 首先,我們先來講講什麼是閉包 簡單來說就是一個定義在函數內部的函數,可以讀取到其他函數內部變數的函數,本質上,閉包就是一個把函數內部和外部連接起來的橋梁 那我們讀取函數內部的 ...
在面試題中,閉包應該是必問的問題吧(以下內容純屬個人理解,歡迎大家指正不足)
下麵我們就簡單的瞭解一下閉包這個東西到底是什麼
首先,我們先來講講什麼是閉包
簡單來說就是一個定義在函數內部的函數,可以讀取到其他函數內部變數的函數,本質上,閉包就是一個把函數內部和外部連接起來的橋梁
那我們讀取函數內部的變數為什麼要用到閉包呢,或者說閉包的作用是什麼?
這就涉及到變數的生命周期問題了,函數內部定義的變數屬於局部變數,局部變數的生命周期是:當它所在的函數被調用的時候,就是開始,當調用執行一旦結束,局部變數就會被釋放,當我們需要函數內部變數時,他已經被釋放了,讀取不到了,這個時候怎麼解決?我們就要想辦法延長他的生命周期
閉包的目的也可以說就是這個,延長局部變數的生命周期,當函數執行完畢以後,局部變數不可以被記憶體釋放,然後讓外部可以訪問到這個變數
那我們如何判斷閉包是不是存在呢
閉包主要有以下幾個特點:
1、函數套函數,閉包一定有嵌套函數
這個意思從閉包的字面定義上其實就可以大概推出來,定義在函數內部的函數;
那為什麼一定要函數套函數呢?因為需要局部變數,閉包的目的就是訪問函數內部的局部變數,如果不定義局部變數,那就達不到我們的目的——延長變數生命周期
2、外層函數一定有局部變數,且內層函數一定操作了外層函數的這個變數
3、外層函數一定把內層函數返回外部,使用return
為什麼要用return返回這個內層函數呢?因為如果不返回這個內層函數,你就沒辦法使用這個閉包,返回內層函數的最終的目的就是讓外部可以訪問到這個閉包,如果外部沒辦法訪問閉包,那閉包怎麼做函數內部和外部溝通的橋梁
在做閉包的問題時,我們還需要註意以下兩點:
1、外層函數被多次調用,都會創建新的作用域,也就是說內層函數操作的外層函數的局部變數之間是不會影響的
這句話簡單來說就是我第一次調用這個外層函數,使用了內部的局部變數 p;我第二次第三次再調用這個外層函數使用變數 p的時候,會創建新的作用域,並不會對之前的調用產生什麼影響
2、外層函數返回的內層函數被調用幾次,內層函數操作的外層函數的局部變數就會變化幾次
上面兩點都可以通過下麵這段代碼看出來
下麵是具體的輸出結果
對前面解釋不明白的可以結合代碼和輸出結果來分析,
第一點:每次的外層函數調用輸出結果都是互不影響的,看每次調用的第一個輸出結果都為0(這裡調用的是外層函數);
第二點,在我【one第一次調用】【two第二次調用】【three第三次調用】的幾次輸出結果中可以看出,我每輸出一次(內層函數被調用一次),變數的值就會發生變化,自增1,我輸出幾次也就是調用了幾次,變數他就變化了幾次
請註意上面雖然都是說調用,但是調用的函數是不同的,調用的是外層函數,變數互不影響,調用的是內層函數,那麼變數變化會根據你調用的次數變化
這裡我也不知道大家能不能明白我到底想表達個啥
閉包的壞處
閉包使函數內部的變數不能被記憶體釋放,這些變數就會占用記憶體,記憶體消耗大,可能會導致記憶體泄露
解決這個問題的辦法就是在不使用這些變數時,及時把不需要的局部變數全部刪除