var a = 12;
function fn() {
var a = new Array(10000000).join('x');
return function () {
var b = 1 + a;
}
}
var f = fn();
结果,占用内存。
图一
例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);
}
我的github https://github.com/zhuanyongxigua/blog
这一篇首先是打算证明一下《三个闭包实例理解闭包对内存的影响》。
一共有10个例子,例7、8、9需要注意。
只测试了Chrome,Chrome版本为
67.0.3396.87(正式版本) (64 位)
例1
结果,占用内存。
图一
例2
结果同上图。如果把例子改成:
结果就是这样了,局部作用域中的函数fn被销毁了。
图二
例3
结果同图二,返回函数没有被全局变量接住。
例4
这是一个延时销毁的例子。
先这样卡主断点:
测试内存结果同图一。
然后让程序运行完成,测试内存的结果就变成了图二。
例5
结果同图一。
例6
结果同图二,没有被返回的函数使用,销毁。
例7
结果同图一,被返回的函数使用的变量被储存了,没有被使用的被销毁了。
例8
结果同图一,变量没有被除返回函数之外的其他函数使用,依然会有内存被占用。
例9
结果同图二,没有被占用,变量a实际上被重新声明了。
例10
结果同图一,内存被占用。 这种会被拿来当做面试题:
总结
闭包环境中的变量会有存储在内存中的条件:返回了一个函数被使用(通常是被赋值给了一个外部的变量,例4和例10是另一种情况),且这个函数所在的执行环境中的变量被这个执行环境中的函数使用。