4

在开发客户端应用程序时,我遇到了一个错误,我认为这与我对使用闭包的不完全理解有关。我已将代码缩减为以下内容:


var fn1 = function(arr){ 
  return function(val){ 
    var idx;
    var x = 20; 
    for (idx in arr) {
      arr[idx]();
    } 
  } 
}

var fn2 = fn1([function(){
  x+= 20; 
  alert(x);
}])

现在在执行时:

fn2()

我收到一个错误: ReferenceError: reference to undefined property "x"

我想知道为什么会出现这个错误,为什么 fn2 不能访问在 fn1 返回的闭包函数的局部范围内定义的变量?

4

2 回答 2

8

简而言之:闭包可以访问与其声明位置相关的父范围,而不是使用它们的位置。

返回的函数fn1可以访问其父函数(fn1本身)的范围,即它可以访问arr. 但是数组中的函数无法访问fn1从它返回的函数内部或内部定义的变量,因为这些函数(数组内部)是在不同的范围内声明的。

关于您尝试使用该代码解决的实际问题,我不确定我是否理解正确。看起来您正在尝试将某些功能应用于某个数字。我不明白为什么那个数字(20在你的例子中)是一个常数而不是一个参数。这是我为此提出的解决方案(没有关闭!):

var applyArrayFunctions = function(arr, x){ 
    for(var i=0; i<arr.length; i++) {
        x = arr[i](x);
    }
    return x;
}

var num = 2;
var fnArray = [
    function(val){
      return val + 20; 
    },
    function(val){
      return val * 2; 
    }
];

console.log(applyArrayFunctions(fnArray, num));​ // logs 44​​​
于 2012-06-17T18:55:45.023 回答
3

我怀疑错误在行x+=20

var x = 20只存在于 . 返回的匿名函数的范围内fn1x+=20之前进行评估fn1,因此x当时甚至不存在。

于 2012-06-17T18:58:52.413 回答