匿名函数中的 JavaScript 上下文

发布于 2024-10-16 10:15:51 字数 239 浏览 4 评论 0原文

我想将一个函数设置为数组中每个元素的属性,但使用不同的参数调用它。我想我可以使用匿名函数来解决它:

for ( var i = 0; i < object_count; i++ ) {
    objects[i].callback = function(e,x,y){ cb(e,x,y,i) };
}

但是,该函数是用 i 当时的值调用的。我将如何保留上下文?

I want to set a function as a property of each element in an array, but call it with different arguments. I thought I'd solve it using an anonymous function:

for ( var i = 0; i < object_count; i++ ) {
    objects[i].callback = function(e,x,y){ cb(e,x,y,i) };
}

However, the function is called with the value that i has at the time. How would I preserve the context?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

往日情怀 2024-10-23 10:15:51

您可以将赋值包装在函数中,或者至少在右侧:

    objects[i].callback = (function(i) { return function(e, x, y) {
      cb(e, x, y, i);
    })(i);

立即调用“外部”匿名函数,将循环变量“i”复制到参数中(我也将其称为“i”;有些人认为这样做很令人困惑,而其他人则说这样做很令人困惑,所以你可以决定:-),然后由返回的“内部”匿名函数使用它。

解决此问题的另一种方法是使用实​​用函数来实现此目的,而不是简单的内联匿名函数。在这种情况下,它会变得有点棘手,因为您希望“i”成为实际回调函数的最后参数。 Functional JavaScript 库有一个很酷的实用程序,可以让您“预填充”选定的参数具有固定值的函数,为您提供一个可以将参数传递给非固定值的函数;它看起来像这样:

  objects[i].callback = (function(e, x, y, i) { return cb(e, x, y, i); }).partial(_, _, _, i);

无论是好还是坏都是风格和观点的问题。

编辑只是喝了一点咖啡 - 我认为我认为我必须使用上面的“partial()”有点愚蠢。事实上,内部函数(“真正的”函数)想要“i”位于参数列表的末尾,这实际上与需要设置的方式无关。上面的例子也可以这样完成:

   objects[i].callback = (function(i, e, x, y) { return cb(e, x, y, i); }).curry(i);

这就不那么奇怪了。 (不过,两者都可以。至少,我认为他们会。:-)

You can wrap the assignment in a function, or the right-hand side at least:

    objects[i].callback = (function(i) { return function(e, x, y) {
      cb(e, x, y, i);
    })(i);

The "outer" anonymous function is called right away, copying the loop variable "i" into an argument (which I also called "i"; some think it's confusing to do that while others say it's confusing not to do it, so you can decide :-) which is then used by the returned "inner" anonymous function.

Another approach to this problem would be to use a utility function for this purpose instead of a simple in-line anonymous function. In this case, it's made slightly tricky because you want "i" to be the last parameter of the actual callback function. The Functional JavaScript library has a cool utility that lets you "pre-populate" selected arguments of a function with fixed values, giving you a function that lets you pass in arguments to the non-fixed ones; it'd look something like this:

  objects[i].callback = (function(e, x, y, i) { return cb(e, x, y, i); }).partial(_, _, _, i);

Whether that's better or worse is a matter of style and opinion.

edit just had a little more coffee - I think that I was being a little silly thinking that I had to use "partial()" above. The fact that the inner (the "real" function) wants "i" at the end of the parameter list is really not relevant to the way things need to be set up. That above example could also be done like this:

   objects[i].callback = (function(i, e, x, y) { return cb(e, x, y, i); }).curry(i);

which is way less bizarre. (Either would work however. At least, I think they would. :-)

番薯 2024-10-23 10:15:51

当您编写

for (var i = something; ...) {
  a[i] = function() { x(i); }
}

函数中的 i 对于所有函数来说都是相同的(它与您在 for 循环范围中定义的变量完全相同。

您想要做什么就是拥有一个特定于每个函数上下文的变量。您可以

for (var i = something; ...) {
  (function () {        // using an anonymous function, we create a private context
     var new_i = i;     // new_i has the value of 'i' but exists solely in this
                        // private context
     a[i] = function() { x(new_i); }
                        // the assigned function now refers a variable of the private
                        // context, which will be different on the following loop
                        // iterations
  })();
}

通过搜索闭包和作用域在 JavaScript 中的工作原理来获取有关此主题的更多信息。

When you write

for (var i = something; ...) {
  a[i] = function() { x(i); }
}

The i in your functions will be the same for all functions (it's the very same variable you define in the scope of your for loop.

What you want to do is to have a variable that's specific for each function context. You could do something like this

for (var i = something; ...) {
  (function () {        // using an anonymous function, we create a private context
     var new_i = i;     // new_i has the value of 'i' but exists solely in this
                        // private context
     a[i] = function() { x(new_i); }
                        // the assigned function now refers a variable of the private
                        // context, which will be different on the following loop
                        // iterations
  })();
}

You can get more information on this topic by searching how closures and scope work in JavaScript.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文