關於javascript閉包(Closure)和return之間的曖昧關係

  什麼是閉包阮一峯老師說的很清楚了,定義在一個函數內部的函數,在本質上,閉包就是將函數內部和函數外部鏈接起來的一座橋樑jquery

  首先要了解Javascript的變量做用域:全局變量局部變量。全局嘛,就是共享,任何一個函數內部能夠直接讀取全局變量;局部嘛,就是私有,不暴露在外的。如何判斷該變量是全局仍是局部,函數內部看它有沒有var進行聲明。沒有var聲明的變量,實際是個全局變量,別被騙咯!瀏覽器

傲嬌的小眼神(別被騙咯)性能優化

  Javascript語言特有的"鏈式做用域"結構(chain scope),子對象會一級一級地向上尋找全部父對象的變量。因此,父對象的全部變量,對子對象都是可見的,反之則不成立。既然子對象能夠讀取父對象的變量,那咱們想獲取一個對象(假設爲f1)裏面的變量,給f1建立一個子對象(假設爲f2),並將子對象return出去,不就能夠在外部訪問到這個對象(f1)的私有變量。f2就是閉包,沒錯,它就是閉包。很少說,代碼如圖:閉包

f2即爲閉包模塊化

  那麼問題來了,你說閉包是爲了獲取一個函數內部的私有數據而建立的,那我直接將一個想要獲取的數據return出去,外部不同能夠獲取嘛,很少說,看權威的jquery源碼:函數

我非要return性能

外部訪問數據優化

  也有人說閉包能夠防止全局變量污染,什麼是全局變量污染?當多人一塊兒開發一個大型項目的時候,每一個人負責一塊,其中定義的全局變量可能會存在命名衝突,當項目進行整合的時候起衝突的全局變量會被覆蓋,這應該很好理解。閉包的應用將變量私有化,能夠起到防止變量全局污染的做用,外部同時也能夠訪問到私有化的變量。解決全局變量污染的問題,能夠結合js模塊化開發思惟,以下圖:url

js模塊化一3d

js模塊化二(閉包)

  二者的區別在圖片中已經闡明瞭,能夠自行試一試。閉包還有一個比較大的用處,相信大家都知道,讓這些變量的值始終保持在內存中。因此注意的一點就是:因爲閉包會使得函數中的變量都被保存在內存中,內存消耗很大,因此不能濫用閉包,不然會形成網頁的性能問題,在IE中可能致使內存泄露。解決方法是,在退出函數以前,將不使用的局部變量所有刪除。(阮一峯老師原話,偷點懶0.0)。

  這句話不知道大家可否瞭解,我簡單闡述下個人想法,必定要認真看完哈!首先全局變量和局部變量生命週期是不一樣的,全局變量存放在一個區域內,具備全局做用域;局部變量放在堆棧中,由編譯器自動分配釋放,存放函數的參數值,局部變量的值等,只有局部做用域,在程序運行期間不是一直存在,而是隻在函數執行期間存在,函數的一次調用執行結束後,變量被撤銷,其所佔用的內存也被收回(GC)垃圾回收機制(GC)原理:垃圾收集器會按照固定的時間間隔,週期性找出再也不使用的變量,而後釋放其佔用的內存。再也不使用的變量也就是生命週期結束的變量,是局部變量,局部變量只在函數的執行過程當中存在,當函數運行結束,沒有其餘引用(閉包),那麼該變量會被標記回收。全局變量的生命週期直至瀏覽器卸載頁面纔會結束,也就是說全局變量不會被當成垃圾回收。當一個局部變量存在引用(閉包),該變量也不會被當成垃圾回收,始終存在於內存中。

  閉包這種將變量始終存儲,你們知道有什麼好處麼?能夠仔細研究想一想,再深剖會發現,閉包在性能優化方面優點很明顯,對比下return,如圖所示:

閉包與return對比

  如上代碼,經過閉包,在外部對數據進行操做時候,紅框內代碼不會再一次執行,也就是f1裏面劈里啪啦一頓猛如虎的操做以後得到的n,存儲到內存中後,外部操做其實是對存儲在內存上的數據進行了操做。相比return,若是外部想得到內部的私有數據再操做,那內部的程序在外部每獲取一次就須要跑一次,這無形中消耗着電腦的性能,因此我以爲,閉包的合理使用,是能夠下降電腦性能的消耗起到必定的優化性能的做用。不合理的使用閉包會致使內存泄漏。

  好了,謝謝你這麼帥,還能看完個人分享,但願對你有所幫助(辛辛苦苦寫了那麼多,兄dei,點個贊再走吧),送你一朵❀。

 

相關文章
相關標籤/搜索