闭包

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

变量的作用域:

变量参考作用域区分,分为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        
原文地址:https://www.cnblogs.com/xlj-code/p/8043425.html