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

50-解决方案

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

5.12.2 解决方案

使用 while 或者 do...while 循环会更快吗?可能不会。可以将前一个循环改写为: 或: 但是两种写法都不比更易读的 for 循环快。

有关for..in循环的警告 决不要将 for..in 循环用于jQuery对象或者任何类型数组的循环读取中。如果数组有任何自定义属性或者方法,它们将和数字型数组元素一起循环读取。例如,下面的代码枚举一个DOM元素——文档主体( i=0 ): 下面的代码似乎也做同样的工作,但是除了 [0] 元素以外,它还会列举所有jQuery方法,如 showcss : 这时应该用前面列举的数组循环来完成。 如果你的页面上有任何代码修改了 Object.prototype ,用附加的方法或者属性扩展所有对象,那么即使是 for..in 循环的“安全”用法也可能遇到问题。除了你想要的内容之外,循环还会列举那些方法或者属性。 我们非常反对扩展 Object.prototype ,因为它会破坏很多代码。实际上,至少在jQuery 1.3.2中,它就因为导致 each() 列举添加的方法或者属性而破坏了jQuery本身。如果你的代码必须工作于这种环境,就必须对所有的循环多加注意,如测试每个对象属性的 hasOwnProperty() 方法。遗憾的是,因为这些额外的测试会降低代码运行速度,所以你必须在速度和健壮性之间做出选择。

使用 for 循环代替 .each() 。在循环读取数组的方法中,下面的循环是难以战胜的:

for( var item, i = −1; item = array[++i] ) {
   // 处理item
}
var i = −1,n = array.length;
while(++i < n){
   var item = array[i];
   // 处理item
}
$('body').each(function(i){ console.log(i);});

但是这里有个例外:这种循环只能在数组没有“假”元素时才能正常工作,也就是说,数组里不能有值为 undefinednullfalse0 或者“”的元素。尽管有这样的限制,这种循环在许多常见情况下还是有用的,例如,在jQuery对象中的循环。只是,一定要将对象缓存在变量中:

var $items = $('.lotsOfElements');
for( var item, i = −1; item = $item[++i] ) {
   // 处理item (DOM节点)
}
var i = 0,n = array.length;
if(i < n)do {
   var item = array[i];
   // 处理item
}
while(++i < n);
for(var i in $('body'))console.log(i);// BAD

像秘诀5.11那样,将对象数组包含在JSON数据中也是常见的:

{
   "names": [
     {
        // ...
        "zip": "48786"
     },
     //重复1000个名字
   ]
}

如果你知道组成 names 数组元素的对象都不为null,使用这种快速循环就很安全了。

为了编写一个更通用的、可以用于任何数组的循环,可以使用你在许多地方都能看到的经典循环:

for( var i = 0; i < array.length; i++ ) {
   var item = array[i];
   //处理item
}

还可以在三个方面改进这种循环:

  • 缓存数组长度。
  • 使用 ++i , 在某些浏览器中它快于 i++
  • 合并循环变量的测试和递增,减少一次名称查找。

结果如下:

for( var i = −1, n = array.length; ++i < n; ) {
   var item = array[i];
   // 处理item
}

注意

可以使用 for..in 循环读取对象(不是数组):

for( var key in object ) {
   var item = object[key];
   // 处理item
}