javascript闭包

认识闭包

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

对于普通函数:

function compare(val1, val2){
    return val1 - val2;
}
var result = compare(5, 10);

其作用域链如下:

        

如下,是创建闭包的常用方式,该函数是为sort函数创建一个比较函数作为参数:

function createComparisonFunction(propertyName){
    return function(object1, object2){
        var val1 = object1[propertyName];
        var val2 = object2[propertyName];
        
        return val1 - val2; 
    }
}
var compareNames = createComparisonFunction("name");
var result = compareNames({..., ...});
compareNames = null;                        //解除都匿名函数的引用,以便释放内存

对于匿名函数而言,其作用域链如下:

         

匿名函数可以访问在createFunctions函数中定义的所有变量,更重要的是,createFunctions函数在执行完毕后其活动对象也不会被销毁,因为匿名函数的作用域仍然在引用这个活动对象。也就是说,createFunctions函数返回后,其执行环境的作用域链会被销毁,但他的活动对象仍会留在内存中,知道匿名函数被销毁。

可见,闭包会比其他函数占用更多的内存,要慎重使用闭包。


闭包与变量
先看下面这个例子:
function createFunctions(){
    var result = new Array();
    for (var i = 0; i < 10; i++){
       result[i] = function(){
           return i;
        };
    }
    return result;
}

从表面上来看,似乎每个函数都应该返回自己对应的索引值,但实际上,每个函数返回都是10,因为每个函数都保存着creatFunctions中的的活动对象,引用的都是同一个变量i,所以最终每个函数中的返回的i的值都是10,但是如下我们将强制使闭包返回我们预期的值:

function createFunctions(){
    var result = new Array();
    for (var i =0; i<10; i++){
       result[i] = function(num){
           return function(){
               return num;
            }   
        }(i);
    }
    return result;
}

这里,通过创建匿名函数,且传入i的值,由于参数是按值传递的,这样就将变量i的值复制给参数num,在匿名函数内部又创建并返回了一个访问num的闭包,这样一来,结果数组中的每个函数都有自己的num变量的副本,于是就可以返回不同的值了。


闭包与this

每个函数在被调用时,其活动对象都会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到自己活动对象为止,因此永远不可能会直接访问外部函数中的这两个变量。如下:

var name = "The Window";
var object = {
    name : "My Object", 
    getNameFunc : function(){
        return function(){
            return this.name ;
        };
    };
}alert(object.getNameFunc()());            //输出"The Window"

那么如何让闭包能够访问呢?只要让外部作用域的this对象保存到闭包能够访问到的变量里就行了!

如下:

var name = "The Window";
var object = {
    name : "My Object", 
    getNameFunc : function(){
        that = this;
        return function(){ 
            return that.name ;
        };
    };
}
alert(object.getNameFunc()());                         //输出"My Object"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值