函数编程-在循环体和异步回调中慎重使用闭包(closure)

由于闭包具有持久性,生成的闭包不会立即被销毁,因此它会持续占用系统资源。如果大量使用闭包,将会造成系统资源紧张,甚至导致内存溢出等错误。

/*   内存泄露是指一块被分配的内存既不能使用,又不能回收,直到浏览器进程结束,由于浏览器垃圾回收方法有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();
方式一:调用函数,得到返回值,强制函数直接量执行再返回一个引用,引用再去调用执行
方式二:调用函数,得到返回值,强制运算符使函数调用执行


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值