闭包概念集合

一、创建闭包

创建闭包的常见方式,就是在一个函数内部创建另一个函数。

二、作用域链

当某个函数被调用的时候,会创建一个执行环境和相应的作用域链,然后使用arguments初始化对象。这个对象叫做活动对象。

在作用域链中,外部函数的活动对象始终处于第二位。以此类推,直到作用域链终点——全局执行环境。 首先,让我先来看看什么叫做活动对象。

function compare(a,b){
    if(a>b){
        return true;
    }else if(a<b){
        return false;
    }else{
        return 0;
    }
}
var result=compare(5,10);//false
console.log(result);

这段代码中,首先定义了compare()函数,然后在全局作用域中调用了它。在调用这个函数的时候,创建了arguments、a、b这三个活动对象。他们处在作用域链的第一位。

而result、compare被称为变量对象,他们处于全局执行环境下,在作用域链中处于第二位。

全局环境的变量对象始终存在,在函数中访问一个变量时,就会在作用域链中寻找具有相应名字的变量。函数执行完毕,活动对象就被销毁。而闭包的特殊就在于此,活动对象没有被销毁!

看这段代码:

function compare(propertyValue){
    return function(obj1,obj2){
        var a=obj1;
        var b=obj2;
        if(a<b){
            return true;
        }else if(a>b){
            return false;
        }else{
            return 0;
        }
    }
}
var fun=compare("value");
console.log(typeof fun);//function
var result=fun(5,10);
console.log(result);//true

函数compare()中包含了一个匿名函数,那么,该匿名函数,也就是闭包的作用域链中,就会有compare()函数的活动对象。因此,该闭包作用域链其实有三节:

第一节,闭包的活动对象,obj1,obj2 和arguments;

第二节,compare()函数的活动对象,arguments和propertyValue;

第三节,全局变量对象,compare。

这意味着什么意思呢?就是在compare()这个函数在执行完毕以后,他的活动对象propertyValue和arguments也不会被销毁。因为匿名函数的作用域链仍然在引用这个活动对象。也就是说,compare()执行完以后,其执行环境的作用域链会被销毁,但是他的活动对象却不会被销毁。除非匿名函数被销毁。

总结:由于闭包会携带外部函数的作用域,所以它会占用更多的内存。建议不要过多使用闭包,会导致内存占用过多。

三、闭包与变量

function fun(){
    var result=new Array();

    for(var i=0;i<4;i++){
        result[i]=function(){
            return i;
        };
    }
    return result;
}
var a=fun();
console.log(a);//Array(4) [, , , ]

猜你喜欢

转载自www.cnblogs.com/qingshanyici/p/10504625.html
今日推荐