用瀏覽器測試幾種閉包占用內存的狀況

用瀏覽器測試幾種閉包占用內存的狀況

@(markdown及附件筆記)[真傳] 個人github github.com/zhuanyongxi…javascript

這一篇首先是打算證實一下《三個閉包實例理解閉包對內存的影響》java

一共有10個例子,例七、八、9須要注意git

只測試了Chrome,Chrome版本爲67.0.3396.87(正式版本) (64 位)github

例1面試

var a = 12;
function fn() {
  var a = new Array(10000000).join('x');
  return function () {
    var b = 1 + a;
  }
}
var f = fn();
複製代碼

結果,佔用內存。瀏覽器

圖一markdown

圖一

例2閉包

var oDiv = document.getElementById("div1");
~function() {
  var fn = function() {};
  fn.data = new Array(10000000).join('x');
  oDiv.onclick = fn;
}();
複製代碼

結果同上圖。若是把例子改爲:函數

var oDiv = document.getElementById("div1");
~function() {
  var fn = function() {};
  fn.data = new Array(10000000).join('x');
  // oDiv.onclick = fn;
}();
複製代碼

結果就是這樣了,局部做用域中的函數fn被銷燬了。測試

圖二

圖二

例3

function fn(){
  var a = new Array(10000000).join('x');
  return function(){
    var b = 1 + a;
  }
}
fn();
複製代碼

結果同圖二,返回函數沒有被全局變量接住。

例4

這是一個延時銷燬的例子。

function fn(){
  var a = new Array(10000000).join('x');
  return function(){
    var b = 1 + a;
  }
}
fn()();
複製代碼

先這樣卡主斷點:

測試內存結果同圖一。

而後讓程序運行完成,測試內存的結果就變成了圖二。

例5

var fn;
function foo() {
  var a = new Array(10000000).join('x');
  function baz() {
    var b = 1 + a;
  }
  fn = baz;
}

foo();
複製代碼

結果同圖一。

例6

function fn() {
  var a = new Array(10000000).join('x')
  return function () {
    console.log("test");
  }
}
var f = fn();
複製代碼

結果同圖二,沒有被返回的函數使用,銷燬。

例7

function fn() {
  var a = new Array(10000000).join('x')
  var b = new Array(10000000).join('x')
  return function () {
    var b = 1 + a;
  }
}
var f = fn();
複製代碼

結果同圖一,被返回的函數使用的變量被儲存了,沒有被使用的被銷燬了。

例8

function fn() {
  var a = new Array(10000000).join('x');
  
  function another() {
    var b = 1 + a;
  }
  
  return function() {
    console.log("test");
  };
}
var f = fn();
複製代碼

結果同圖一,變量沒有被除返回函數以外的其餘函數使用,依然會有內存被佔用。

例9

function fn() {
  var a = new Array(10000000).join('x');
  return function(a) {
    var b = 1 + a;
  }
}

var f = fn();
複製代碼

結果同圖二,沒有被佔用,變量a實際上被從新聲明瞭。

例10

(function(a) {
  setTimeout(function() {
    var b = 1 + a;
  }, 0);
})(new Array(10000000).join('x'));
複製代碼

結果同圖一,內存被佔用。 這種會被拿來當作面試題:

for(var i = 1; i < 10; i++) {
  (function(i) {
    setTimeout(function() {
      console.log(i);
    }, 0);
  })(i);
}
複製代碼

總結

閉包環境中的變量會有存儲在內存中的條件:返回了一個函數被使用(一般是被賦值給了一個外部的變量,例4和例10是另外一種狀況),且這個函數所在的執行環境中的變量被這個執行環境中的函數使用。

相關文章
相關標籤/搜索