天天看点

闭包《javascript高级程序设计》笔记

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

    创建方法:在一个函数内部创建另一个函数。

function createCompareFunction(propertyName) {
    //在一个函数中返回另一个函数,该函数可以继续使用该函数的外部函数的变量。
        return function(object1,object2) {
            var value1 = objcet1.propertyName;
            var vllue2 = object2.propertyName;
            if(value1 < value2) {
                return -;
            }
            else if(value1 > value2) {
                return ;
            }
            else {
                return ;
            }
    }
}
           

//执行createCompareFunction()函数,返回一个函数,然后改函数的执行环境的作用域链就销毁了,按理说该函数的参数(函数的参数相当于函数的局部变量)也应该随函数的执行环境的作用域链一起销毁才是啊,应该再也访问不到该函数的参数了,但是返回的函数却还能访问该变量(propertyName)。

var compareFunction = createCompareFunction();

//定义一个函数,该函数返回另一个函数。
function sayName(name) {
//该内部函数可以访问外部函数的参数name
    return function(object) {
        alert(object[name]);
    }
}
//调用sayName()函数,并传入了参数,然后该sayName()函数的执行环境的作用域链就注销了,但是的但是,该函数返回的函数却还留着sayName()函数的活动对象,因为返回的匿名函数还引用着该活动对象,直到该返回的匿名函数被销毁后,外部函数sayName()的活动对象才会被销毁。这个活动对象保存着name的值。
var res = sayName("zheng");
//该返回的函数res传入参数"zheng",这个值和name一样,如果sayName()的活动对象和执行环境的作用域链一起注销了,那么调用res时,传入一个对象,该对象就应该读取不了外部函数sayName()的name变量,但是该res函数却读取到了name属性值,和传入对象的属性zheng一致,那么就返回了该传入对象的属性zheng的值:lijing。
res({zheng:"lijing"});
           

2、例子

function compare(value1,value2) {
    return value1-value2;
}
           
当在全局创建compare()函数时,会创建一个预先包含全局变量对象的作用域链,这个作用域链被保存在内部的[[Scope]]属性中。
当调用compare()函数时,会创建一个执行环境,然后通过复制函数[[Scope]]属性中的作用域链形成了作用域链,然后使用arguments对象和命名参数的值来初始化函数的活动对象(在这里作为变量对象使用)。对于compare()函数的执行环境而言,其作用域包含两个变量对象,一个是全局的活动对象,另一个是全局活动对象。
活动对象似乎和变量对象是表达的是同一个意思。
一个函数被调用结束后,该函数的活动对象就会被销毁,但是若该活动对象没有被销毁,就形成了闭包。而内存中会保留全局作用域(全局变量对象)。
           

继续阅读