Javascript-变量更新

Javascript - Variable updating

本文关键字:更新 变量 Javascript-      更新时间:2023-09-26

这可能是一个简单的问题,但现在已经是深夜了,我无法理解。

这是我的代码

$(document).ready(function () {
var items = getNumber();
for (var i = 0; i < items.length; i++) {
    var test = items[i].action;
    test();
}
});
function getNumber()
{
var items = [];
for (var i = 0; i < 5; i++) {
    var num = i * 10;
    items.push({ id: i, number: num, action: function () { alert(i) } });
}

return items
}

有人能向我解释一下为什么警报输出总是5吗?我希望alert参数是添加到数组时的索引。它似乎是动态的。

如果你也能发布一个解决方案,我将非常感谢

这是JavaScript变量作用域的一个常见问题:新变量仅在新的执行上下文中引入,因此,在有问题的代码中,i所有操作回调中共享。

无论如何,以下是遵循标准习惯用法的更正代码:

function getNumber()
{
  var items = [];
  for (var i = 0; i < 5; i++) {
    var num = i * 10;    
    items.push({
      id: i, number: num,
      // _i is a new variable for each callback
      action: (function (_i) {
        // use separate (one per callback) _i variable
        return function () { alert(_i) }
      })(i) // pass in current value for loop
    });
  }
  return items
}

或者,如果不喜欢所有的嵌套,可以使用"命名"函数来执行相同的任务。关键是,闭包是在新的执行上下文中创建(并从中返回)的,这样就可以关闭不同的变量:

function getNumber()
{
  function mkAction (i) {
      return function () { alert(i) }
  }
  var items = [];
  for (var i = 0; i < 5; i++) {
    var num = i * 10;    
    items.push({
      id: i, number: num,
      action: mkAction(i)
    });
  }
  return items
}

另一种方法是使用ES5:中的Function.bind

function getNumber()
{
  var items = [];
  for (var i = 0; i < 5; i++) {
    var num = i * 10;    
    items.push({
      id: i, number: num,
      action: (function (_i) { alert(_i) }).bind(null, i)
    });
  }
  return items
}

(请注意,即使没有本机浏览器支持,也可以使用新的执行上下文/闭包来模拟Function.bind。请参阅MDC文档。)

另请参阅:

  • 循环中的JavaScript闭包——简单实用的示例

  • 在循环中向setTimeout传递函数:总是最后一个值?

  • JavaScript闭包是如何工作的?