关于javascript关闭的困惑

时间:2012-06-17 18:50:52

标签: javascript closures

虽然开发人员是客户端应用程序,但我遇到了一个错误,我认为这与我对闭包使用的不完全理解有关。我已将我的代码修改为以下内容:


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返回的本地闭包函数范围内定义的变量?

2 个答案:

答案 0 :(得分: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​​​

答案 1 :(得分:3)

我怀疑错误在x+=20

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