關於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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...