for循环中的Javascript闭包:为什么循环索引我不可见?

时间:2013-01-05 21:55:56

标签: javascript closures

假设给定一个函数(它是一个对象的一部分,不要担心)

makeClosures : function(arr, fn) {},

其中参数是,首先是一个数组,例如[1, 2, 3, 4]和第二个函数(称之为doSomeStuff),它将给定数字

平方

var doSomeStuff = function (x) { return x * x; }

makeClosures应返回与arr大小相同的数组,其中每个元素都包含对基本上调用doSomeStuff的函数的引用。

所以这是我的实施:

makeClosures : function(arr, fn) {
  var funcs = [];

  for (var i = 0; i < arr.length; i++) {
    var f = function() {
      return fn(arr[i]);
    };

    funcs.push(f);
  }

  return funcs;
},

问题是

运行程序时,f的返回值为NaN。我尝试使用实际数字(return fn[1]return fn(arr[0]))然后它有效,这意味着问题出在arr[i](未定义?)。我怀疑内部函数f没有看到循环索引i。为什么呢?

2 个答案:

答案 0 :(得分:0)

Pointy的评论:

“在JavaScript中,词法范围发生在函数级别。在循环中构造的所有函数共享相同的变量”i“。在循环结束时,”i“的值是什么?右:arr。长度.arr [arr.length]的值是多少?“

返回的函数在循环迭代后执行,并且var i仍然在范围内,其值为array.length,超出了数组的范围。

此外,你应该在for循环之外声明f,在函数级别创建范围,而不是在循环内部创建,所以当循环的每次迭代已经存在时,你声明f。

答案 1 :(得分:-1)

不确定天气会有所帮助,但这是我尝试和工作过的。

var arr = [1, 2, 3, 4]
var fn = function (x) { return x * x; }

function makeClosures(arr, fn) {
    var funcs = [];   

    for (var i = 0; i < arr.length; i++) {     

        var f =  fn(arr[i]);       

        funcs.push(f);
    }

    return funcs;
}

myarr = makeClosures(arr, fn);

for (var j = 0; j < myarr.length; j++) {
    alert(arr[j] + ' square is : ' + myarr[j]);
}