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

来源:https://www.cnblogs.com/xuxiaoqiangAndHM/archive/2018/12/01/10024098.html
-Advertisement-
Play Games

什麼是閉包?阮一峰老師說的很清楚了,定義在一個函數內部的函數,在本質上,閉包就是將函數內部和函數外部連接起來的一座橋梁。 首先要瞭解Javascript的變數作用域:全局變數和局部變數。全局嘛,就是共用,任何一個函數內部可以直接讀取全局變數;局部嘛,就是私有,不暴露在外的。如何判斷該變數是全局還是局 ...


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

  首先要瞭解Javascript的變數作用域:全局變數局部變數。全局嘛,就是共用,任何一個函數內部可以直接讀取全局變數;局部嘛,就是私有,不暴露在外的。如何判斷該變數是全局還是局部,函數內部看它有沒有var進行聲明。沒有var聲明的變數,實際是個全局變數,別被騙咯!

傲嬌的小眼神(別被騙咯)

  Javascript語言特有的"鏈式作用域"結構(chain scope),子對象會一級一級地向上尋找所有父對象的變數。所以,父對象的所有變數,對子對象都是可見的,反之則不成立。既然子對象可以讀取父對象的變數,那我們想獲取一個對象(假設為f1)裡面的變數,給f1創建一個子對象(假設為f2),並將子對象return出去,不就可以在外部訪問到這個對象(f1)的私有變數。f2就是閉包,沒錯,它就是閉包。不多說,代碼如圖:

f2即為閉包

  那麼問題來了,你說閉包是為了獲取一個函數內部的私有數據而創建的,那我直接將一個想要獲取的數據return出去,外部不一樣可以獲取嘛,不多說,看權威的jquery源碼:

我非要return

外部訪問數據

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

js模塊化一

js模塊化二(閉包)

  兩者的區別在圖片中已經闡明瞭,可以自行試一試。閉包還有一個比較大的用處,相信你們都知道,讓這些變數的值始終保持在記憶體中。所以註意的一點就是:由於閉包會使得函數中的變數都被保存在記憶體中,記憶體消耗很大,所以不能濫用閉包,否則會造成網頁的性能問題,在IE中可能導致記憶體泄露。解決方法是,在退出函數之前,將不使用的局部變數全部刪除。(阮一峰老師原話,偷點懶0.0)。

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

  閉包這種將變數始終存儲,大家知道有什麼好處麽?可以仔細研究想想,再深剖會發現,閉包在性能優化方面優勢很明顯,對比下return,如圖所示:

閉包與return對比

  如上代碼,通過閉包,在外部對數據進行操作時候,紅框內代碼不會再一次執行,也就是f1裡面劈里啪啦一頓猛如虎的操作之後獲得的n,存儲到記憶體中後,外部操作實際上是對存儲在記憶體上的數據進行了操作。相比return,如果外部想獲得內部的私有數據再操作,那內部的程式在外部每獲取一次就需要跑一次,這無形中消耗著電腦的性能,所以我覺得,閉包的合理使用,是可以降低電腦性能的消耗起到一定的優化性能的作用。不合理的使用閉包會導致記憶體泄漏。

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

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • mysql是一種關係型資料庫管理系統。以mysql5.7版本為例,安裝過程如下: 首先百度出mysql的官網,進入:(以下是自己安裝失敗的過程,直接下拉最後看大佬的安裝過程吧,就是那個紅紅的網址) 找到mysql的下載社區,找到對應的版本,這裡以mysql5.7為例: 這裡我們選擇zip格式安裝,對 ...
  • [20181130]如何猜測那些值存在hash衝突.txt--//今年6月份開始kerrycode的1個帖子提到子查詢結果緩存在哈希表中情況:--//鏈接:http://www.cnblogs.com/kerrycode/p/9099507.html,摘要:通俗來將,當使用標量子查詢的時候,ORAC ...
  • [20181130]hash衝突導致查詢緩慢.txt--//昨天看了鏈接https://jonathanlewis.wordpress.com/2018/11/26/shrink-space-2/,演示了Shrink Space導致--//執行語句緩慢的情況,我自己重覆測試,實際上這樣發生的概率還是 ...
  • [20181130]control file sequential read.txt--//昨天上午探究了大量控制文件讀的情況,鏈接:http://blog.itpub.net/267265/viewspace-2222146/--//今天做一些細節探究:1.環境:SYS@xxxxx1> @ ver ...
  • 1、ipa包解壓縮:右鍵.ipa包,使用【歸檔實用工具/unarchiver】打開 2、進入解壓縮後的payload目錄,右鍵ipa包 顯示包內容 3、找到info.plist文件,直接拖拽出來 4、使用plist編輯器打開 info.plist,就可以查看CFBundleDisplayName、C ...
  • 超簡單釘釘打卡破解教程 ​ 公司前幾天要用釘釘打卡 作為拖延症的我肯定天天遲到 所以就一直找辦法可以遠程打卡 什麼teamviewer 大牛定位都不是特別好用要麼要兩台手機要麼就是收費什麼的 不過前兩天找到一個不錯的軟體我目前一直在用而且還是免費的 就是需要xposed框架支持 為了能不遲到還是折騰 ...
  • 1. NSOperation、NSOperationQueue 簡介 NSOperation、NSOperationQueue 是蘋果提供給我們的一套多線程解決方案。實際上 NSOperation、NSOperationQueue 是基於 GCD 更高一層的封裝,完全面向對象。但是比 GCD 更簡單 ...
  • 時間飛快,轉眼間8102還差一個月就over了,順了順好幾天沒理的鬍渣兒,好像已經老了不少。 不,我還很年輕!雖然年終還沒到,但好像也差不多了。 幾經輾轉,年底前終於拿到了微信的offer,可以說是今年一大幸事了。 是一個結束,結束本命年的坎坷;是一個開始,開始新的徵程。 這篇雜文就簡單記錄一下微信 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...