针对迭代器,这里有几个特点:
1.访问一个聚合对象的内容而无需暴露它的内部。
2.为遍历不同的集合结构提供一个统一的接口,从而支持同样的算法在不同的集合结构上进行操作。
3.遍历的同时更改迭代器所在的集合结构可能会导致问题。
简单的说:封装实现,然后迭代器的聚合对象不用关心迭代的过程,从而符合SRP原则。
自己实现一个迭代器
function each(obj, callback) {
var i = 0;
var value;
var length = obj.length;
for (; i < length; i++) {
callback(obj[i]);
}
}
var arr = ['a', 'b', 'c'];
each(arr, function(name) {
console.log(name);
})
这样就满足了迭代模式的设计原则,对于集合内部结果常常变化各异,我们不想暴露其内部结构,但又想让客户代码透明地访问其中的元素,通过回调把逻辑给解耦出来。但是这样的处理其实太简单了,我们还要考虑至少四种情况:
1.聚合对象,可能是对象,字符串或者数组等类型
2.支持参数传递
3.支持上下文的传递
4.支持循环中退出
jQuery的each迭代器
jQuery的each方法从使用上就要分2种情况:
$.each()
$(selector).each()
$.each()函数和$(selector).each()是不一样的,后者是专门用来遍历一个jQuery对象的,是为jQuery内部服务的。
$.each()函数可用于迭代任何集合,无论是“名/值”对象(JavaScript对象)或数组。在迭代数组的情况下,回调函数每次传递一个数组索引和相应的数组值作为参数。(该值也可以通过访问this关键字得到,但是JavaScript始终将this值作为一个Object,即使它是一个简单的字符串或数字值。)该方法返回其第一个参数,这是迭代的对象。
jQuery的实例方法最终也是调用的静态方法,我们在之前就解释过jQuery的实例与原型方法共享的设计。
// 可见内部是直接调用的静态方法
each: function( callback ) {
return jQuery.each( this, callback );
}
jQuery.each静态方法
each: function( obj, callback ) {
var length, i = 0;
if ( isArrayLike( obj ) ) { // 数组
length = obj.length;
for ( ; i < length; i++ ) {
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
break; // 只要有一个元素返回false,就从循环中退出
}
}
} else { // 对象
for ( i in obj ) {
if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
break; // 只要有一个元素返回false,就从循环中退出
}
}
}
return obj;
}
网友评论