1. 概念

  指有权访问另一个函数作用域中的变量函数。创建闭包的常见方式,就是在一个函数内部创建另一个函数。 

function a(propertyName){
    return function(object1,object2){
        var value1 = object1[propertyName];  
        var value2 = object2[propertyName];  
        return value1-value2;    
    };
}

  a()函数中的函数为匿名函数,当a()函数返回后,其执行环境的作用域链会被销毁,但它的活动对象仍然会留在内存中,直到匿名函数被销毁后,a()的活动对象才会被销毁。

2. 闭包只能取得包含函数中任意变量的最后一个值。

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

每个函数的作用域链中都保存着createFunctions()函数的活动对象,所以它们引用的都是同一个变量i。可以创建另一个匿名函数强制让闭包的行为符合预期。

function createFunctions(){
    var result = new Array();
    for(var i = 0; i < 10; i++){
        result[i] = function(num){
            return function(){
                return num;
            };
        }(i);
    }
      return result; //1,2,3,4,5,6,7,8,9
}               

将变量i的值传递给num,在这个匿名函数内部,又创建并返回了一个访问num的闭包,这样result数组中的每个函数都有自己num变量的一个副本,因此就可以返回各自不同的数值了。

3. this对象

在全局函数中,this等于window,而当函数被作为某个对象的方法调用时,this等于那个对象。不过,匿名函数的执行环境具有全局性,因此其this对象通常指向window。

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

每个函数在被调用时,其活动对象都会自动取得两个特殊变量: this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象位置(本身为1,全局为2),因此永远不能直接访问外部函数中的这两个变量。不过,把外部作用域中的this对象保存在一个闭包能够访问到的变量里,就可以让闭包访问该对象了。

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

应用场景:

(1)在内存中维持一个变量。

(2)通过保护变量的安全实现JS私有属性和私有方法(不能被外部访问)