6

昨晚在阅读 jQuery Cookbook (Oreilly) 时,我遇到了一个 each 函数,它产生了一个我似乎无法在书中或在线找到答案的问题。我用于这个问题的代码是从jQuery 网站上找到的,我把它包含在下面作为参考:

<script>
    $(document.body).click(function () {
      $("div").each(function (i) {            //Where does the 'i' come from?
        if (this.style.color != "blue") {
          this.style.color = "blue";
        } else {
          this.style.color = "";
        }
      });
    });
</script>

我想知道“i”参数的来源和用途,因为我看不到它来自哪里(客户端代码)以及它的用途?作为一个 Java 人,当我熟悉 Java 上下文中的方法或“函数”参数时,我会更容易掌握这个概念。

在这里,我没有看到客户端代码(我假设它在库中),也没有看到它(i)在函数中的相关性,因为它没有被引用。

社区中的某个人可以对此给出明确的解释或向我推荐这方面的指南吗?

我理解每个函数的目的和“this”参考,所以你不需要解释这些,除非你觉得它与这个问题的未来观众有关。

4

4 回答 4

13

在这种情况下,没有必要声明i. 该each方法的签名在 jQuery 文档中说明:

.each( function(index, Element) )

如您所见,它接受一个参数,而该参数是一个接受 2 个参数的函数,index并且Element.

在您的代码中,i是 的标识符index,它在每次调用时由 jQuery 传递给回调函数(每次迭代一次)。它还传递了第二个参数,但您没有为它声明一个标识符,因此它只能通过arguments对象访问。

arguments您可以通过记录该对象来准确查看传递给回调的内容:

​$("div").each(function () { //No arguments listed in callback signature...
    console.log(arguments); //But arguments are still passed
});​​

这是上面的一个工作示例

这是来自 jQuery 本身的相关代码(添加了评论):

//...
each: function( object, callback, args ) {
    //...

    //Iterate over the matched set of elements
    for ( ; i < length; ) {
        /* Call the callback in the context of the element, passing in the 
           index and the element */
        if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
            break;
        }
    }
}
于 2012-06-19T07:55:50.787 回答
2

当你调用时$().each(),你传递给它一个函数引用。该.each()函数的工作方式是,对于 jQuery 对象中的每个元素,它以当前元素作为上下文调用您给它的函数(即在函数调用内部,this变量是当前元素)。

现在,当 jQuery 调用你给它的函数时,它可以传入可选参数,就像你在代码中调用函数一样。有了.each(),每当它调用你给它的函数时,它都会传入两个参数:一个索引当前元素

就好像 jQuery 像这样调用它:

$('div').each(foo);

// results in something like
for(var i=0; i < $('div').length; i++) {

    // calling the foo function
    foo(i, $('div')[i]);

    // this is simplified, of course. 
    // this doesn't take into account the function context, or "this" variable.
}

您可能会发现官方文档也更好地解释了它。

于 2012-06-19T07:57:09.023 回答
1

正如它在 API 中所说,“i”是索引。

如果您想在均匀元素和不均匀元素之间做出区别,这可能会很有用

像:

$(document.body).click(function () {
  $("div").each(function (i) {            //Where does the 'i' come from?
    if (i % 2 == 0) {
      this.style.color = "blue";
    } else {
      this.style.color = "";
    }
  });
});
于 2012-06-19T07:58:11.023 回答
1

这些参数的“起源”是“让我们不同于prototype.js”。
由于很少需要索引,因此以相反的顺序传递参数更有意义。

考虑这个例子:
哪个调用和函数最有意义?

$('.my-selector').each( modifyNodeA );
$('.my-selector').each( function(){
    // this wrapper anonymous function is cruft
    modifyNodeB(this);
});
$('.my-selector').each( modifyNodeB ); // this one won't work
$('.my-selector').each( modifyNodeC );
$('.my-selector').each( function(){
    // just using 'this' makes sense here.. it's evident that this is a jQuery closure
});

function modifyNodeA(i, node) {
    // this one works...  but gotta have i in the func signature.
    //   it won't be used and doesn't make contextual sense
    //  can also use 'this', but where the heck did it come from..  it's not evident
}

function modifyNodeB(node, i) {
    // 'i' could/should be an optional 2nd param
    //   this function could function on it's own
}

function modifyNodeC() {
    // gotta use the magic 'this' scope var..  where did it come from?
    // contextually, it would be nice to have the var passed... it is... as the 2nd param!
}

这里简单总结一下:

为什么我仍然更喜欢 Prototype 而不是 jQuery - 第 8 节 - 其他 Nit-picks

$.each并且$().each都首先将索引传递给回调,然后将值传递给回调。这意味着如果我不需要索引,我不能像在 Prototype 中那样将它从函数声明中删除。

于 2014-09-05T19:40:18.780 回答