闭包与变量
我们知道:闭包只能取得包含函数中的任何变量的最后一个值,这就会导致某些副作用,下面代码很好说明了这个bug。
function createFunctions(){
var result = new Array();
for(var i=0;i<10;i++){
result[i] = function(){
return i;
};
};
return result;
}
上面这个函数是一个生成函数数组的函数。表面上看每个函数都会返回对应的i值,但实际上,每个函数都是返回10。因为每个函数的作用域链都保存着createFunctions()函数的活动对象,因此他们引用的都是同一个变量i,当createFunctions()返回后,每个变量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会传参给num,在第一个匿名函数内又创建并返回了一个访问num的闭包,这样一来result数组中的每个函数就有了自己的num变量的副本,可以返回不同的值了。
通俗地说,就是在闭包里再创建一个闭包,利用闭包特性将次级闭包的最终值返回给父级闭包,使得父级闭包的返回值互异