• 闭包


    看了许多博客和教程大概理解了闭包的概念和大致作用,总结一下。

    变量的作用域:

    变量参考作用域区分,分为2种,全局变量和局部变量,全局变量什么时候都可以访问,除非将它销毁,但终究,使用全局变量是不好的,容易引起混乱,因为任何地方都可以用。但局部变量只有在函数内部可以访问,函数执行完毕后,该函数内部的局部变量被销毁,函数外部无法访问,比如:

    function fn1(){
        var age=23;
    }
    fn1();
    alert(age);   //报错

    那么问题来了,我想使用函数内部的局部变量,怎么办呢,这里,就可以使用闭包:

    function fn1(){
        var age=23;
        function fn2(){
            return age;
        }
        return fn2;
    }
    var num=fn1();
    alert(num());    //23

    以上代码,首先定义了一个fn1函数,函数内部定义了一个局部变量age并初始化,值为23,接下来定义了一个fn2函数,该函数内部将变量age返回,注意,这里是关键,因为fn2内部是可以访问到父函数的局部变量的,最后一步,将fn2函数返回。接下来,将fn1函数正式执行,并将返回值保存在变量num中,返回值也就是fn2整个函数,再将num执行并弹出,得到fn1的局部变量23。成功将该局部变量取出。

    所谓闭包,这里,应该就是fn2这个函数。闭包将变量age一直保存在内存中,永远不会销毁。

    这里,就有一个问题来了,闭包有啥用,这样也可以得到该局部变量呀,比如:

    function fn1(){
        var age=23;
        return age;
    }
    alert(fn1());    //23

    但这里其实只是简单的将变量返回,并没有永远保存在内存中,执行完毕age还是销毁了,你再调用一次,只是重复的定义,返回。这里有个例子可以证明:

    function fn1(){
        var age=23;
        age++;
        return age;
    }
    alert(fn1());  //24
    alert(fn1());  //24
    alert(fn1());  //24

    这里我想实现变量age累加,调用了3次函数,结果每次都是24,因为变量定义---返回---销毁。重复3次而已,但闭包可以实现:

    function fn1(){
        var age=23;
        function fn2(){
            age++;
            return age;
        }
        return fn2;
            }
    var num=fn1();
    alert(num());    //24
    alert(num());    //25
    alert(num());    //26

    这里就很明了了,对比之下,变量age永远在内存中,"num()",就可以得到age,随时可以取用。

    作用:

    有啥用?2个作用:1、可以取得函数的局部变量。2、而且这些局部变量的值永远在内存中。

    注意点:由于闭包会使变量一直存在,不会垃圾回收,内存消耗大。所以在明确不再需要时,及时销毁。比如:

    function fn1(){
        var age=23;
        function fn2(){
            age++;
            return age;
        }
            return fn2;
    }
    var num=fn1();
    alert(num());    //24
    alert(num());    //25
    alert(num());    //26
    num=null;        //销毁
    alert(num());    //num is not a function    

    附加:使用闭包返回多个变量

    如果想取用某个函数的数个局部变量怎么办呢,这里可以用数组或者对象的方法

    数组的方法:

    function fn(){
        var name="张三",
            age=23;
        var arr=[function(){return name;},function(){return age;}];
        return arr;
    }
    var item=fn();
    var a=item[0]();   //name
    var b=item[1]();   //age
    console.log(a+"-----"+b);   // 张三-----23

    对象的方法:

    function fn(){
        var name="张三",
            age=23;
        var obj={
            getName:function(){
                return name;
            },
            getAge:function(){
                return age;
            }
        }
        return obj;
    }
    
    var person=fn();
    console.log(fn().getName());   // 张三
    console.log(fn().getAge());    // 23        
  • 相关阅读:
    是否需要有代码规范
    小学四则运算生成程序(支持分数)总结
    HDU 4035 Maze 期望dp
    UVA
    HDU 3853 LOOPS 期望dp
    POJ 2096 Collecting Bugs 期望dp
    HDU 4405 Aeroplane chess 期望dp
    Codeforces Round #341 (Div. 2) E. Wet Shark and Blocks dp+矩阵加速
    HDU 4616 Game 树形dp
    HDU 4126 Genghis Khan the Conqueror 最小生成树+树形dp
  • 原文地址:https://www.cnblogs.com/xlj-code/p/8043425.html
Copyright © 2020-2023  润新知