functionrandomString(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; }
functiongetData() { var demoData = []; for (let i = 0; i < 1000; i++) { demoData.push(randomString(1000)) } } getData();
當我們執行上方函式時,其實完全不會佔用記憶體,其主要原因就如同上方所述,函式當執行完畢之後,記憶體是會被釋放的,但若將 var demoData = []; 改放置掛載在全域下會發生什麼事情?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
functionrandomString(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } var demoData = []; functiongetData() { for (let i = 0; i < 1000; i++) { demoData.push(randomString(1000)) } } getData();
在此可以看到 strings 暫用了 23 MB (此為 Firefox 瀏覽器)
接下來我們將 demoData 放回函式內再來看一次會發生什麼事情
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
functionrandomString(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } functiongetData() { var demoData = []; for (let i = 0; i < 1000; i++) { demoData.push(randomString(1000)) } } getData();
可以發現記憶體明顯少非常的多。
而在此閉包的概念在於記憶體是否可以再次被參考,而因為 var demoData = []; 是建立在 getData 底下,因此在函式結束任務被釋放記憶體之後就無法再次參考該變數,所以如果你想取得這個變數是無法的。
而在此所謂的記憶體是否可以再次的定義是什麼呢?讓我們加入 setTimeout 來試一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
functionrandomString(length) { var result = ''; var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; var charactersLength = characters.length; for (var i = 0; i < length; i++) { result += characters.charAt(Math.floor(Math.random() * charactersLength)); } return result; } functiongetData() { var demoData = []; for (let i = 0; i < 1000; i++) { demoData.push(randomString(1000)) } setTimeout(function() { demoData; }, 10000); } getData();