【问题标题】:Javascript function questionJavascript函数问题
【发布时间】:2011-02-22 05:55:57
【问题描述】:

我搜索了这个看似简单的问题,但找不到答案,所以...

假设我有一个需要设置回调的循环。我的回调函数如下所示:

function callback(var1) { // code }

现在我的循环是这样的:

for( //condition)
{
  var x = something_different_each_time;
  document.getElementById('foo').addEventListener('click', function() { callback(x); }, false);
}

现在看起来即使循环运行 n 次,匿名函数也只编译一次——因此每次调用回调都使用相同的参数调用(即使 x 在循环中每次都不同)。

我一定在这里遗漏了一些东西。非常感谢任何帮助! :)

【问题讨论】:

标签: javascript loops closures


【解决方案1】:

您应该在调用回调函数之前计算 x!

for( //condition)
{
  //var x = something_different_each_time;
  document.getElementById('foo').addEventListener('click', function() { 
   var x = something_different_each_time;
   callback(x); }, false);
}

【讨论】:

  • 这不是真正的问题。还是谢谢。
【解决方案2】:
【解决方案3】:

问题是for语句的块并没有创建一个新的范围,因为x变量属于它的封闭范围,所有匿名函数都引用同一个变量...

使用另一个函数创建一个新的词法环境以在每次迭代中保存x 的值:

for(/*condition*/) {
  var x = something_different_each_time;
  document.getElementById('foo').addEventListener('click', function () {
    return function(y) {
      callback(y);
    };
  }(x), false);
}

【讨论】:

  • 我认为您的匿名函数表达式周围缺少一些大括号。
  • @deceze:不,只有当函数位于可能导致函数表达式和函数声明之间出现语法歧义的地方时才需要括号,在这种情况下,函数位于函数调用的参数列表,显然是在表达式上下文中,没有歧义......例如:(function (fn) { fn();})( function () {alert ('hi');} );
  • @deceze:也许是一个更好的例子:var foo = function () { return 'bar'; }(); 函数调用没有问题...foo === 'bar';
【解决方案4】:

是的,x 将引用封闭范围内的同一个变量,并且由于该函数稍后执行,因此它将具有最后一个值 x。试试这个:

.addEventListener(
    'click',
    (function (i) {
        return function () { callback(i); }
    })(x),
    false
);

这将创建一个闭包,其中锁定了当前值x

【讨论】:

    猜你喜欢
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 2018-12-06
    • 2017-06-27
    相关资源
    最近更新 更多