当前位置:嗨网首页>书籍在线阅读

27-讨论

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.6.3 讨论

jQuery的 .each() 方法不是什么高技术。实际上,如果截取jQuery 1.3.2的实现在大部分典型使用(在jQuery对象中循环)中的实际代码,就会发现它只是一个相当简单的循环:

jQuery.each = function( object, callback ) {
   var value, i = 0, length = object.length;
   for(
     value = object[0];
     i < length && callback.call( value, i, value ) !== false;
     value = object[++i]
   ) {}
   return object;
};

each() 函数还可以用更熟悉的方法编写:

jQuery.each = function( object, callback ) {
   for(
     var i = 0, length = object.length;
     i < length;
     ++i
   ) {
     var value = object[i];
     if( callback.call( value, i, value ) === false )
        break;
     }
     return object;
};

我们可以编写类似的函数,以其他实用的方式循环读取数组或者jQuery对象。比 .slowEach() 更简单的一个例子是以逆序循环读取jQuery对象:

//以相反的顺序循环读取数组或者jQuery对象
jQuery.reverseEach = function( object, callback ) {
   for( var value, i = object.length; --i >= 0; ) {
     var value = object[i];
     console.log( i, value );
     if( callback.call( value, i, value ) === false )
        break;
     }
};
//以相反的顺序循环读取"this"(一个jQuery对象)
jQuery.fn.reverseEach = function( callback ) {
   jQuery.reverseEach( this, callback );
   return this;
};

上面的代码并不试图处理 .each() 所处理的所有情况,只适用于典型jQuery代码的常规情况。

有趣的是,自定义迭代器可以完全不使用循环。 .reverseEach() 和标准的 .each() 都使用比较常规的循环,但是在 .slowEach() 中没有明确的JavaScript循环。为什么会这样?如何在不使用循环的情况下读取所有元素?

Web浏览器中的JavaScript没有在许多语言中都能找到的 sleep() 函数,所以不能这样暂停脚本的执行:

doSomething();
sleep( 1000 );
doSomethingLater();

作为替代,和JavaScript中的任何异步活动一样, setTimeout() 函数有一个回调参数,每隔一段时间就调用回调函数。 .slowEach() 方法在 setTimeout() 回调函数中递增“循环”变量 i ,利用闭包在两次“循环”之间保留变量值。(闭包的讨论参见秘诀5.2。)

.each() 一样, .slowEach() 直接在jQuery对象或者数组上操作,所以完成循环之前对数组的任何更改都会影响循环。和 .each() 不同的是, .slowEach() 是异步的(对回调函数的调用发生在 .slowEach() 返回之后), 所以如果在 .slowEach() 返回之后、回调之前改变jQuery对象或其元素,这也会影响到循环。