由于闭包具有持久性,生成的闭包不会立即被销毁,因此它会持续占用系统资源。如果大量使用闭包,将会造成系统资源紧张,甚至导致内存溢出等错误。
/*
内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束,由于浏览器垃圾回收方法有bug,会产生内存泄露 */
/**
* 把数组类型的参数中每个元素的值分别封装在闭包结构中,
* 然后把闭包存储在一个数组中,并返回这个数组。
*/
function f(x) {
var a = [];
for (var i = 0; i < x.length; i++) {
var temp = x[i];
a.push(function() {
/* 闭包中temp并不是固定的,它会随着根据函数运行环境中的变量temp的值变化而更新,
这样会导致数组元素的值都是字符‘c’,而不是a,b,c。 */
/*由于循环变量i递增之后,最后的值是3,x[3]超出了数组的长度,所以运行结果是undefined*/
console.log(temp + " " + x[i]);
});
}
return a;
}
function e() {
var a = f(["a", "b", "c"]);
for (var i = 0; i < a.length; i++) {
a[i]();
}
}
e(); // 'c undefined'*3
(放进a数组里面的temp 和 x[i] 依旧是
变量)
---------------------------------------解决方案------------------------------------------------------------------
function f(x) {
var a = [];
for (var i = 0; i < x.length; i++) {
var temp = x[i];
/* 为闭包再包裹一层函数,然后运行函数,并把外界动态值传递给它,
这个函数接收这些值后传递给内部的闭包函数,从而阻断了闭包与最外层函数实时联系 */
a.push((function(temp, i) {
return function() {
console.log(temp + " " + x[i]);
}
})(temp, i));
}
return a;
}
function e() {
var a = f(["a", "b", "c"]);
for (var i = 0; i < a.length; i++) {
a[i]();
}
}
e();
方式一:调用函数,得到返回值,强制函数直接量执行再返回一个引用,引用再去调用执行
方式二:调用函数,得到返回值,强制运算符使函数调用执行