闭包就是有权访问另一个函数作用域中的变量的函数。要理解闭包,首先要理解函数创建和执行过程中,作用域链的变化。
以下面这个比较函数为例
//1、创建compare函数
function compare(value1,value2){
if(value1<value2){
return -1;
}else if(value1>value2){
return 1;
}else{
return 0;
}
}
//2、调用compare函数
var resul=compare(5,10);
上图为调用compare 过程产生的作用域链之间的关系 ]
1,、创建compare函数时,会创建一个预先包含全局变量对象作用域链,保存在内函数的[[scope]]属性中。
2、当调用compare函数时,会为函数创建一个执行环境,从[[scope]]属性复制对象构建执行环境的作用域链,此后又有一个活动对象被创建,作为内部函数的变量对象推入执行环境作用域链的前端。
所以在compare函数的作用域链中,就包含本地活动对象和全局变量对象。
闭包的情况:
function createComparisonFunction(propertyName) {
return function (obj1, obj2) {
var value1= obj1[propertyName];
var value2= obj2[propertyName];
if (value1< value2)
return -1;
if (value1> value2)
return 1;
if (value1== value2)
return 0;
}
}
//1.创建函数
var compareNames = createComparisonFunction("name");
//2.调用函数
var result = compareNames({ name: "d", age: 20 }, { name: "c", age: 27 });
//3.解除对匿名函数的引用(以便释放内存)
compareNames =null;
1,、外部函数createComparisonFunction调用完,它的作用域链会被销毁,返回一个内部函数compareNames的定义,这时会创建一个预先包含全局变量对象和外函数变量对象的作用域链,保存在内函数compareNames的[[scope]]属性中,所以外函数的变量对象仍然保存在内存中。
2、内部函数compareNames调用时,创建执行环境,从[[scope]]属性复制对象构建执行环境的作用域链,此后再把内部的变量对象推入执行环境作用域链的前端。
3、内部函数调用完毕时,并且置空销毁,它的预作用域链就被销毁,不再引用着外函数的变量对象,此时外函数变量对象才会被回收。
上图为调用compareNames 过程产生的作用域链之间的关系