为什么$.each()不能遍历每个项目?

54

我有以下标记,其中包含10个类名为indentpre元素:

​<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>
<pre class="indent"></pre>​

我正在使用以下 jQuery .each() 函数来迭代遍历每个元素:

$(function(){    
    $.each(".indent", function(index){
       alert(index); 
    });    
});​

我希望看到10个警报,但是我只看到了7个。

-- 查看代码 --


然而,使用 $(".indent").each() 可以按预期工作:

$(function(){    
    $(".indent").each(function(index){
       alert(index); 
    });    
});​

-- 查看 Fiddle --


查看$.each()的文档,我明白它们之间有所不同:

$.each()函数与$(selector).each()不同,后者仅用于遍历jQuery对象。

但我不明白为什么在这种情况下它不能遍历所有元素。

这是为什么?


18
使用 console.log 代替 alert,能够获得更好的调试数据。 - zzzzBov
10
$.each(".indent") 不会遍历 .indent 对象,它是在 ".indent" 字符串上进行遍历。 - Maurício Giordano
2
只是一点小建议:最好使用console.log而不是alert。对于测试来说更好,关闭所有这些弹出窗口真的很麻烦。 - andyrandy
1
@luschn 谢谢,早期版本确实使用了 console.log(),但经过数小时的苦思冥想和反复确认,每一行代码都必须更改以防万一 :P - Curtis
3个回答

145
$.each(".indent", function(index){

迭代器并不遍历$('.indent')元素,而是遍历长度为7个字符的字符串".indent"

参见文档


基于jQuery源代码的更详细解释:

jQuery首先检查第一个参数obj(这里是你的字符串)是否具有length属性:

var ...
        length = obj.length,
        isObj = length === undefined || jQuery.isFunction( obj );

你的字符串具有一个length属性(而不是一个函数),isObj的值为false

在这种情况下,执行以下代码:

for ( ; i < length; ) {
    if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) {
        break;
    }
}

因此,考虑函数f,以下代码:

$.each(".indent", f);

等同于

for (var i=0; i<".indent".length; i++) {
    var letter = ".indent"[i];
    f.call(letter, i, letter);
}

(您可以使用var f = function(i,v){console.log(v)}记录字母,或者使用var f = function(){console.log(this)}来提醒您关于call的微妙之处。)


1
我在不到一分钟的时间里看到一个JS加法函数获得了9个赞,但是.each()却获得了17个赞...只能为了好玩而点赞 :) - Zoltan Toth
2
非常感谢。我最近也遇到了这种问题。 - Nylo Andy

38
您正在遍历字符串,您应该向$.each方法传递一个对象或数组:
$(function(){    
    $.each($(".indent"), function(index){
       alert(index);
    });    
});

22

$.each可以迭代数据集合。由于您传递了一个包含7个字符的字符串,它将为每个字符迭代一次。请参考以下使用示例:

$.each([52, 97], function(index, value) { 
  alert(index + ': ' + value); 
});

1
指出 value 参数是加1的好方法...我不知道为什么JQuery决定颠倒这两个参数,通常你更需要 value 而不是 index - Izkata
3
@Izkata 对于你通常使用的this值(好吧,并不总是)。这就是为什么index是最有用的参数,也是第一个。 - Denys Séguret

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接