闭包

时间:2020-04-25
本文章向大家介绍闭包,主要包括闭包使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

闭包:指有权访问另一个函数作用域中变量的函数。

function parentFunc(){
    var a = 1;
    function childFunc(){
        console.log(a);
    }
    return childFunc();
}

闭包的特征:
<1>函数内再嵌套函数;
<2>内部函数可以调用外部函数的参数和变量;
<3>参数和变量不会被垃圾回收机制回收。

闭包的好处:能够实现封装和缓存。使用闭包主要是为了封装对象的私有属性和私有方法,闭包可以避免全局变量的污染。
闭包的缺点:闭包会常驻内存,会增大内存使用量,使用不当很容易造成内存泄漏。

闭包经典问题:

function parentFunc(){
    var arr = [];
    for(var i = 0;i<5;i++){
        arr[i] = function (){
            return i;
        }
    }
    return arr;
}
console.log(parentFunc()[0]());  //5
console.log(parentFunc()[1]());  //5

这里就展现出了几个关键信息,首先分析一下代码:循环中创建了一个匿名函数并将其赋值给arr数组中对应索引的元素,匿名函数作用是返回i值。此时,arr数组中存放的是匿名函数,而匿名函数还没有执行。当调用parentFunc()函数时返回arr数组,再单独执行数组中的元素保存的匿名函数,此时循环已经执行完,所以i值为5。接下来再去调用其它数组元素中的匿名函数也样会获得数值5。
要解决这个闭包所产生的问题,有两种办法:
<1>立即执行匿名函数

function parentFunc(){
    var arr = [];
    for(var i = 0;i<5;i++){
        arr[i] = (function (){
            return i;
        })();
    }
    return arr;
}
console.log(parentFunc());  //[0,1,2,3,4]

<2>使用let关键字声明变量:使用let声明变量会形成块级作用域

function parentFunc(){
    var arr = [];
    for(let i = 0;i<5;i++){
        arr[i] = function (){
            return i;
        };
    }
    return arr;
}
console.log(parentFunc()[0]());  //0
 

原文地址:https://www.cnblogs.com/hello9102/p/12774511.html