迭代jQuery和非jQuery对象
jQuery提供了一个对象迭代器实用程序
.each()以及一个jQuery集合迭代器.each()。这些不可互换。另外,还有一些有用的方法可以调用 .map(),.map()这可以使我们常用的迭代用例之一变快。
$.each()
$.each()是循环遍历对象,数组和类似数组的对象的泛型迭代器函数。普通对象通过它们的命名属性进行迭代,而数组和类似数组的对象通过它们的索引进行迭代。
$.each()本质上是一个传统for或for-in循环的直接替换。鉴于:
var sum = 0;
var arr = [ 1, 2, 3, 4, 5 ];
那么这个:
for ( var i = 0, l = arr.length; i < l; i++ ) {
sum += arr[ i ];
}
console.log( sum ); // 15
可以用这个替换:
$.each( arr, function( index, value ){
sum += value;
});
console.log( sum ); // 15
请注意,我们不必访问,arr[ index ]因为值方便地传递给回调$.each()。
另外,给出:
var sum = 0;
var obj = {
foo: 1,
bar: 2
}
那么这个:
for (var item in obj) {
sum += obj[ item ];
}
console.log( sum ); // 3
可以用这个替换:
$.each( obj, function( key, value ) {
sum += value;
});
console.log( sum ); // 3
同样,我们不必直接访问,obj[ key ]因为值直接传递给回调函数。
请注意,这$.each()是针对普通对象,数组,非jQuery集合的类数组对象。
这将被认为是不正确的:
// Incorrect:
$.each( $( "p" ), function() {
// Do something
});
==对于jQuery集合,使用.each()。==
.each()
.each()直接在jQuery集合上使用。它迭代集合中的每个匹配元素并对该对象执行回调。集合中当前元素的索引作为参数传递给回调函数。值(在这种情况下是DOM元素)也被传递,但是回调在当前匹配元素的上下文中被触发,所以this关键字指向当前元素,如其他jQuery回调所期望的那样。
例如,给定以下标记:
<ul>
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
.each() 可能会这样使用:
$( "li" ).each( function( index, element ){
console.log( $( this ).text() );
});
// Logs the following:
// Link 1
// Link 2
// Link 3
问题经常被提出,“如果this是元素,为什么有第二个DOM元素参数传递给回调?
无论是有意还是无意,执行环境都可能改变。当一直使用关键字时this,很容易混淆自己或其他开发人员阅读代码。即使执行上下文保持不变,使用第二个参数作为命名参数的可读性也会更高。例如:
$( "li" ).each( function( index, listItem ) {
this === listItem; // true
// For example only. You probably shouldn't call $.ajax() in a loop.
$.ajax({
success: function( data ) {
// The context has changed.
// The "this" keyword no longer refers to listItem.
this !== listItem; // true
}
});
});
链接有时.each()是不必要的
许多jQuery方法隐式遍历整个集合,将其行为应用于每个匹配的元素。例如,这是不必要的:
$( "li" ).each( function( index, el ) {
$( el ).addClass( "newClass" );
});
这很好:
$( "li" ).addClass( "newClass" );
<li>文档中的每一个都会添加“newClass”类。
另一方面,有些方法不会迭代集合。.each()在设置新值之前需要从元素获取信息时是必需的。
这不会工作:
// Doesn't work:
$( "input" ).val( $( this ).val() + "%" );
// .val() does not change the execution context, so this === window
相反,这是如何写的:
$( "input" ).each( function( i, el ) {
var elem = $( el );
elem.val( elem.val() + "%" );
});