• JS学习笔记——闭包


    1. 什么是闭包

    简单的说,闭包是指一个函数这个函数的执行环境。下面是一个最简单的闭包。函数test()根据作用域链的规则访问到了函数外面的value变量。

    var value = "pxz";
    function test() {
        console.log(value);
    }
    

    上述例子跟我们常见的闭包不太一样,常见的闭包形式是函数嵌套函数并且返回函数。我们再看上面那个例子,变量value赋给了全局对象,我们希望避免全局变量污染,就要把这个闭包放进函数中。如果是一次性的函数,就写成立即执行函数;如果需要调用,就写成返回函数形式。

    一般创建闭包的方式,是在一个函数中创建另一个函数,并将该函数作为返回值返回。一般情况下,一个函数返回了,那么这个函数的活动对象(变量对象)就会被销毁,这个变量对象就不在当前作用域链上了,但是闭包跟一般情况不同。

    2.闭包用途

    闭包可用来实现私有变量,具体可参考JS学习笔记——私有变量。

    3.一个闭包常见的错误

    1.经典闭包例子中,test函数的返回值是一个匿名函数组ary,咋一看,匿名函数组里的每一个函数返回各自的索引值。但其实并不是这样的。匿名函数组里的每一个函数返回的值一样且都为n。我们调用了test函数,返回还是函数,赋给fun。在fun里可以访问到fun外test函数中的变量,比如var i,即使此时已经从test函数中返回。我们可以形象地把这个过程理解为返回函数ary闭包了外层函数的变量i。由于变量i在外层函数只有一份拷贝,所以函数组ary返回的i都是一个i,test函数执行完毕后,i变成了n。

    要使得返回的函数组里的每个函数都不一样,我们需要为每个返回函数拷贝一份变量i。在2.立即执行函数中,没有直接使用外层函数变量i,而是将i作为函数参数传入,这样就能在函数内部拷贝一份变量了。

    3.返回函数中,我们在2.立即执行函数的基础上外包一层函数,使得满足闭包要求,返回函数。

    //1.经典闭包例子
    function test(n) {
        ary = [];
        for(var i = 0; i < n; i++) {
            ary[i] = function() {return i;};
        }
        return ary;
    }
    var fun = test(5)[4];
    console.log(fun());//5
    
    //2.立即执行函数-拷贝变量
    //每一份i都有拷贝,但这不是闭包,返回值不是函数
    function test(n) {
        ary = [];
        for(var i = 0; i < n; i++) {
            ary[i] = (function(x) {return x;})(i);
        }
        return ary;
    }
    console.log(test(5)[4]);//4
    
    //3.返回函数
    //在2的基础上,在外面套一层函数
    function test(n) {
        ary = [];
        for(var i = 0; i < n; i++) {
            ary[i] = (function(x) {
            	return function() {
            		return x;
            	}
            })(i);
        }
        return ary;
    }
    console.log(test(5)[4]());//4
    

    【Reference】

    1. 《javascript高级程序设计》(第3版)
    2. 大部分人都会做错的经典JS闭包面试题 http://www.cnblogs.com/xxcanghai/p/4991870.html
    3. 「每日一题」JS 中的闭包是什么? https://zhuanlan.zhihu.com/p/22486908
  • 相关阅读:
    最大组合的数 A
    2106. 求对称字符串的最大长度 A
    内存分配 A
    242. 子串匹配 A
    【LeetCode 1055】形成字符串的最短路径 A
    给定差值的组合 A
    1791 设备编号 A
    最长的指定瑕疵度的元音子串 A
    1898. 【认证试题】遥控小车 A
    1792 服务器集群网络延迟 A
  • 原文地址:https://www.cnblogs.com/season-peng/p/6899476.html
Copyright © 2020-2023  润新知