摘要:一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區所以參數和變量不會被垃圾回收機制回收。使用不當會很容易造成內存泄露。最后,垃圾回收器完成內存清除工作,銷毀那些帶標記的值并回收它們所占用的內存空間。
1.什么是閉包?閉包有啥特性以及存在什么問題?
概念:閉包是指有權訪問另一個函數作用域中的變量的函數。下面的outer就形成了一個閉包:
function outer(){ const name="nagi"; return function inner(){ console.log(name); } } let p=outer(); } let p=outer();
一般來講,當函數執行完畢后,局部活動對象就會被銷毀,內存中僅保存全局執行環境中的變量對象,但閉包有所不同。
當outer()執行完后,因為inner函數的作用域鏈在引用outer的活動對象,所以它并不會被銷毀,而是仍然留在內存中,
除非inner函數也銷毀它的活動對象才會被銷毀。比如使p=null;
特性: 由上面的代碼可以得出以下幾個特性:
a. 函數嵌套函數,作為一個函數變量的一個引用,當函數返回時,其處于激活狀態。 b. 函數內部可以引用外部的參數和變量。 c. 一個閉包就是當一個函數返回時,一個沒有釋放資源的棧區,所以參數和變量不會被垃圾回收機制回收。
優點:
a. 減少全局變量的污染 b. 可以有私有變量的存在
function counter(){ let n=0; function add(){ n++; console.log(n); } return {n:n, add:add} } const c1=counter(); const c2=counter(); // 它和c1分別存入了不同的堆內存中 c1.add(); // 1 c1.add(); // 2 c1.n; // 0 // 此處的n是基本類型,除非重新賦值,否則不會變! c2.add(); // 1 c1和c2互不干涉,都有自己的新的作用域鏈和新的私有變量 注意!!父函數每次調用會產生新的閉包
缺點(問題):
a.常駐內存,增加內存使用量。 b. 使用不當會很容易造成內存泄露。
另:閉包的多種寫法可以參照這里:JavaScript閉包(closure)2.js中的垃圾回收機制
原理:js中有自動回收管理內存機制,它的原理是會定期(周期性地)找出那些不再繼續使用的變量,然后釋放其占用的內存。
內存管理:
1. 分配內存(不管是基本類型還是引用類型) 2. 使用內存(對變量,函數等讀取或寫操作) 3. 釋放內存(使用垃圾回收機制回收內存)回收方式 1.引用計數
**含義:**跟蹤記錄每個值被引用的次數。 **工作機制:** 當聲明一個變量并將一個引用類型值賦給它時,則這個值的引用次數就是1; 如果同一個值又被賦給另一個變量,則該值的引用次數加1; 相反,如果包含對這個值引用的變量又被賦了其他值,則這個值的引用次數減1; 當這個值的引用次數為0時,則說明沒有辦法再訪問這個值了; 這樣,當垃圾收集器下次再運行時,便會釋放這種引用次數為0的值所占的內存。
問題:
這種方式有一個嚴重的問題,即“循環引用”。 意思是對象A中包含一個指向對象B的指針,而對象B也包含一個指向對象A的指針, 這樣當函數執行完畢后,因為其引用也就永遠不會為0,所以對象A和B將繼續存在, 如果對象所在函數被重復調用,就會導致大量內存得不到回收。
function problem(){ let objA=new Object(); let objB=new Object(); objA.someOtherObj=objB; objB.antherObj=objA; }2.標記清除(常用方式)
原理:垃圾回收器會在運行時給存儲在內存中的所有變量加一個標記。 (當變量進入環境時,就交這個變量標記為“進入環境”。而當變量離開環境時,則將其標記為“離開環境”。) 然后,它會去掉環境中的變量以及被環境中的變量引用的變量的標記(閉包)。 而在這些完成之后再被加上標記的變量將被視為準備刪除的變量,原因是環境中的變量已經無法訪問到這些變量了。 最后,垃圾回收器完成內存清除工作,銷毀那些帶標記的值并回收它們所占用的內存空間。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/108822.html
摘要:系列目錄復習資料資料整理個人整理重溫基礎篇重溫基礎對象介紹重溫基礎對象介紹重溫基礎介紹重溫基礎相等性判斷本章節復習的是中的關于閉包,這個小哥哥呀,看看。這里隨著閉包函數的結束,執行環境銷毀,變量回收。 本文是 重溫基礎 系列文章的第十九篇。今日感受:將混亂的事情找出之間的聯系,也是種能力。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎】...
摘要:內存泄露內存泄露概念在計算機科學中,內存泄漏指由于疏忽或錯誤造成程序未能釋放已經不再使用的內存。判斷內存泄漏,以字段為準。 本文是 重溫基礎 系列文章的第二十二篇。 今日感受:優化學習方法。 系列目錄: 【復習資料】ES6/ES7/ES8/ES9資料整理(個人整理) 【重溫基礎】1-14篇 【重溫基礎】15.JS對象介紹 【重溫基礎】16.JSON對象介紹 【重溫基礎】1...
摘要:線程的劃分尺度小于進程,使得多線程程序的并發性高。線程在執行過程中與進程還是有區別的。每個獨立的線程有一個程序運行的入口順序執行序列和程序的出口。從邏輯角度來看,多線程的意義在于一個應用程序中,有多個執行部分可以同時執行。 showImg(https://segmentfault.com/img/bVbv2GE?w=900&h=400); 前言 本文講解 56 道 JavaScript...
摘要:該對象包含了函數的所有局部變量命名參數參數集合以及,然后此對象會被推入作用域鏈的前端。如果整個作用域鏈上都無法找到,則返回。此時的作用域鏈包含了兩個對象的活動對象和對象。 前端學習:教程&開發模塊化/規范化/工程化/優化&工具/調試&值得關注的博客/Git&面試-前端資源匯總 歡迎提issues斧正:閉包 JavaScript-閉包 閉包(closure)是一個讓人又愛又恨的somet...
閱讀 3220·2021-11-12 10:36
閱讀 1288·2019-08-30 15:56
閱讀 2449·2019-08-30 11:26
閱讀 559·2019-08-29 13:00
閱讀 3616·2019-08-28 18:08
閱讀 2756·2019-08-26 17:18
閱讀 1908·2019-08-26 13:26
閱讀 2439·2019-08-26 11:39