@(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是另外一種狀況),且這個函數所在的執行環境中的變量被這個執行環境中的函數使用。