首頁  >  文章  >  web前端  >  講解 JS 記憶體管理機制及驗證

講解 JS 記憶體管理機制及驗證

coldplay.xixi
coldplay.xixi轉載
2020-12-30 17:34:412647瀏覽

javascript欄位介紹記憶體管理機制及驗證

講解 JS 記憶體管理機制及驗證

推薦(免費):JavaScript(影片)

作用域

JavaScript 的變數被作用域所限制,如果超出了作用域,那麼變數就沒有辦法再被使用,這樣做的優點是:

  • 可以避免當前的變數轉為全域變數
  • 有效限制變數的作用區域

而變數作用域也會依照宣告方式的不同,產生不同的作用域:

  • 未宣告:全域變數
  • var 宣告:作用域在函數
  • letconst 宣告:作用域在{}

var 宣告的變數

在函數內宣告的變數其作用域會被限制在該函數的呼叫堆疊中,在外部無法直接得到該作用域內的變數。下面的範例中, fn 函數內的變數在全域下是沒有辦法查看的。

function fn() {
  var a = 1;
}
fn();
console.log(a); // 无法得到 fn 函数內的 a 变量

所以常用 "立即函數" 來限制變數的作用域,主要是避免全域變數的產生。

(function() {
  var b = 1;
})();
console.log(b); // 无法得到 fn 函数內的 b 变量

let、const 宣告的變數

ES6 之後所新增的letconst 作用域則與過去不同,改用{} 作為作限制用域的方式,這讓for 迴圈及部分語法避免產生多餘的變數來影響作用域。

var 不同的是 const 所定義的變數作用域被限制在 {} 中。所以這個範例中的變數 c 可在外部得到值,d 則無法取到。

{
  var c = 1;
  const d = 1;
}
console.log(c); // 1
console.log(d); // Uncaught ReferenceError: d is not defined,无法取到变量 d

記憶體管理機制

#每當我們新增一個變數時,在記憶體中就會佔用一個位置來保存它的值,以便在程式後續運行時可以多次使用。

下面的程式碼會在記憶體中開啟一個 a 的空間來儲存數字 1 的值。

var a = 1

流程如下:

  1. 開啟一個記憶體空間來存放變數 a ,不過這時還沒有賦值(原因可參考:Hoisting)

講解 JS 記憶體管理機制及驗證

  1. a 賦值。

講解 JS 記憶體管理機制及驗證

所有的變數都會佔用記憶體空間,除此之外物件、陣列的屬性以及函數參數等也會用相同的概念進行佔用。呼叫一個函數時,每個函數的作用域也會重複的進行記憶體佔用。隨著應用程式越來越複雜的情況下,如果持續的佔用記憶體而沒有進行適當的釋放,那麼記憶體可能會被耗盡。

JavaScript 引擎具有記憶體回收的機制,會釋放不再使用的變數內存,其基本概念為:當沒有任何的引用指向它時就會釋放記憶體。

來自MDN:collectible if there are zero references pointing to it.

記憶體釋放的驗證

##下面用一個例子來說明及驗證內存釋放的機制,先用一段函數來產生一個非常長的字串,長字串會佔用大量的記憶體空間。

在呼叫

randomString 函數後會傳回一個很長的字串:

function randomString(length) {
  var result = '';
  var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  var charactersLength = characters.length;
  for (var i = 0; i 案例一:讓變數維持在可引用的狀態(不會釋放記憶體) <h4></h4>定義一個全域變數<p>demoData<code>,這個變數會持續維持可被引用的狀態。 </code></p><pre class="brush:php;toolbar:false">var demoData = []; // 全局变量
function getData() {
  for (let i = 0; i 執行這段程式碼後,進入 Chrome DevTools 中的 Memory 頁,這個功能可以得到目前頁面所佔用的記憶體狀況。接下來點擊 "Take snapshot" 按鈕。 <p></p><p><img src="https://img.php.cn/upload/image/189/951/684/1609320713198525.png" title="1609320713198525.png" alt="講解 JS 記憶體管理機制及驗證"></p>可以看到目前執行完這段程式碼後佔用了 6.2MB 的記憶體空間(注意:任何瀏覽器環境和外掛程式都會影響所佔用的記憶體狀態)。 <p></p><p><img src="https://img.php.cn/upload/image/742/181/269/1609320718742831.png" title="1609320718742831.png" alt="講解 JS 記憶體管理機制及驗證"></p>案例二:使變數無法再次被引用(執行後釋放記憶體)<h4></h4>限制變數的作用域,使變數無法再被外部引用。 <p></p>此段程式碼仍然會執行這個函數,也會將值賦值給變量,但外部無法再引用 <p>demoData<code> 的值。 </code></p><pre class="brush:php;toolbar:false">function getData() {
  var demoData = []; // 局部变量
  for (var i = 0; i <p>然后回到 Memory 页点击 "Take snapshot" 重新取得内存的状态,接下来会得到与前面不同的结果,这次只占用了 1.2MB 的内存(其中 5MB 被释放掉了)</p><p><img src="https://img.php.cn/upload/image/148/641/618/1609320723163241.png" title="1609320723163241.png" alt="講解 JS 記憶體管理機制及驗證"></p><p><strong>总结</strong></p><p>通过前面的例子,我们知道了作用域以及内存之间的关系,而内存管理也是前端打工人必须要掌握的知识(除了控制内存的使用大小,还需在必要时保留而不被释放)。</p>

以上是講解 JS 記憶體管理機制及驗證的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除