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