定义: 闭包是指可以访问函数作用域以外的变量的函数。
function createComparisonFunction(propertyName) { return function(object1,object2) { var value1 = object1[propertyName]; var value2 = object2[propertyName]; if(value1 < value2) { return -1; } else if(value1 > value2) { return 1; } else { return 0; } }; }View Code
在上述代码中,匿名函数function中访问到了外部函数中的变量propertyName。即使这个内部函数被返回了,而且是在其他地方被调用了,但它仍然可以访问变量propertyName。
//函数体在执行环境的作用域中处于第一位 function compare(value1,value2) { if(value1 < value2) { return -1; } else if (value1 > value2) { return 1; } else { return 0; } } var result = compare(5,10); //在执行环境的作用域链中处于第二位View Code
以上代码先定义了compare()函数,然后又在全局作用域中调用了它。当调用compare()时,会创建一个包含arguments、value1和value2的活动对象。
无论什么时候在函数中访问一个变量时,就会从作用域链中搜索具有相应名字的变量。一般来讲,当函数执行完毕后,局部活动对象就会被销毁,内存中仅保存全局作用域。但是,闭包的情况又有所不同。内部的函数会将外部函数的活动对象添加到自己的作用域链中。
二:闭包和变量
作用域链的这种配置机制引出了一个值得注意的副作用,即闭包只能取得包含函数中任何变量的最后一个值。
function createFunctions() { var result = new Array(); for(var i=0; i<10;i++) { result[i] = function(){ return i; }; } return result; } var arrayFuns = createFunctions(); for(k = 0;k< 10 ; k++) { console.log(arrayFuns[k]()); }View Code
因为每个函数的作用域链中都保存着createFunctions()函数的活动对象,所以它们引用的都是同一个变量i。当createFunctions()函数返回后,变量i的值是10,此时每个函数都引用着保存变量i的同一个变量对象,所以在每个函数内部i的值都是10.