【问题标题】:undefined in Closures In For Loops在 For 循环中的闭包中未定义
【发布时间】:2016-03-20 20:45:44
【问题描述】:

var createShoutOuts = function(numbers_list){
  var shoutOuts = [];
  for (var j = 0; j < numbers_list.length; j++) {
    shoutOuts.push(function() {
      var shout_out = 'This is shout out number ' + (j+1);
      console.log(shout_out + '. The number is ' + numbers_list[j]);
    });		
  }
  return shoutOuts;
};

var performShoutOuts = function(user_numbers){
  var readyForShout = createShoutOuts(user_numbers);
  for (var i = 0; i < readyForShout.length; i++) {
    readyForShout[i]();
  };
};

performShoutOuts([2,4,8]);

我创建上述内容是为了自学闭包。输出总是:

'这是喊出来的数字 4。这个数字是未定义的'

我知道它总是会显示数字 4,因为被推入 shoutOuts 数组的匿名函数具有对 j 变量的引用,而不是 j 变量值的副本。因此,当readyForShout[i](); 调用匿名函数时,for 循环已经运行并且 i 的值为 4。

我不明白为什么它说未定义?因为在我看来,传递给performShoutOuts 的数组应该存储在闭包中,因此在执行readyForShout[i](); 时应该可以访问。

我错过了什么?

【问题讨论】:

  • 您缺少 闭包。您根本没有使用闭包概念!在我的答案中运行 sn-p 并查看控制台。 :)
  • 当您运行函数 j = 3 时,结果中为 4。 numbers_list[4] 也未定义。

标签: javascript loops closures


【解决方案1】:

尝试真正使用闭包:

var createShoutOuts = function(numbers_list){
  var shoutOuts = [];
  for (var j = 0; j < numbers_list.length; j++) {
    shoutOuts.push((function (j) {
      return function () {
        var shout_out = 'This is shout out number ' + (j+1);
        console.log(shout_out + '. The number is ' + numbers_list[j]);
      };
    })(j));
  }
  return shoutOuts;
};

var performShoutOuts = function(user_numbers){
  var readyForShout = createShoutOuts(user_numbers);
  for (var i = 0; i < readyForShout.length; i++) {
    readyForShout[i]();
  };
};

performShoutOuts([2,4,8]);

【讨论】:

  • 谢谢@praveen。但为什么?我在函数中有一个函数,并且该内部函数正在利用外部函数变量(在这种情况下是传入的 numbers_list 参数)。我认为这就是闭包的概念——函数中的函数引用外部函数的局部变量。
猜你喜欢
  • 2021-08-30
  • 2022-01-19
  • 2011-01-12
  • 1970-01-01
  • 2011-09-28
  • 1970-01-01
  • 2012-12-15
  • 1970-01-01
相关资源
最近更新 更多