for循环而不是while循环

时间:2011-08-24 00:09:42

标签: jquery

通过jQuery源阅读我偶然发现了以下代码(可用here):

for (; i < length;) {
    if (callback.apply(object[i++], args) === false) {
        break;
    }
}

为什么此处使用for循环而不是while循环?

7 个答案:

答案 0 :(得分:44)

我投票支持那些对编码风格不好的人。这是我可以看到for循环和放置在数组下标中的i++的唯一解释。我认为这会更好:

while (i < length && callback.apply(object[i], args)) {
    i++;
}

或者,如果您碰巧认为原始示例中的===运算符具有值,则:

while (i < length && callback.apply(object[i], args) !== false) {
    i++;
}

这样做的另一个可能原因可能是性能优化。虽然我把这个快速benchmark放在一起似乎反驳了这个理论。在Windows上,上面的while循环比Chrome中的原始for循环快20%,在IE和Firefox中,两个循环执行相同的操作。在OS X上,for循环在Firefox中有10%的优势,Chrome中两者没有区别,而Safari更喜欢while循环6%。

因此,从性能的角度来看,这是一次洗礼。如果根据市场份额进行判断,您可能需要针对Windows上的Chrome进行优化,然后再针对Mac上的Firefox进行优化,在这种情况下,while循环将是首选。

对我说,性能优化不太可能是这个代码的一个因素。我回到我原来的理论,它只是一个糟糕的编码风格的例子,使它超越了代码审查过程。

答案 1 :(得分:26)

可能是因为它是从for (x in obj)循环“重构”的:http://james.padolsey.com/jquery/#v=1.3.2&fn=jQuery.each

答案 2 :(得分:21)

这是the commit that introduced this oddity

提交消息:

  

jquery核心:$.each$.curCSS的代码缩减。

从差异中抓取:

-        for ( var i = 0, length = object.length; i < length; i++ )
-          if ( callback.apply( object[ i ], args ) === false )
+        for ( ; i < length; )
+          if ( callback.apply( object[ i++ ], args ) === false )

似乎作者错过了将for更改为while的机会。

答案 3 :(得分:6)

首先,在for循环上使用while循环永远不会有长度成本,但是您使用for循环获得了额外的功能,因此有些编码器总是使用for

for(;<condition>;){}
while(<condition>){}

那就是说,我认为这里的目的可能是为了与周围的代码保持一致。

例如,这是原始代码的一部分。正如您所看到的,在此代码中,您可以始终保持“for”循环模式,因此感觉更加一致:

if (args) {
    if (isObj) {
        for (name in object) {
            if (callback.apply(object[name], args) === false) {
                break;
            }
        }
    } else {
        for (; i < length;) {
            if (callback.apply(object[i++], args) === false) {
                break;
            }
        }
    }
}

将此与用while替换第二个循环进行比较。当您阅读此代码时,您必须从“for”循环思维模式切换到“while”循环思维模式。现在我不了解你,但我发现在上面的循环条件之间切换,而不是下面的循环条件,我的眼睛稍微快一些。这是因为在上述情况下我可以专注于条件,而在下面的情况下,我的眼睛每次都会重新阅读whilefor,因为它们是不同的:

if (args) {
    if (isObj) {
        for (name in object) {
            if (callback.apply(object[name], args) === false) {
                break;
            }
        }
    } else {
        while (i < length) {
            if (callback.apply(object[i++], args) === false) {
                break;
            }
        }
    }
}

答案 4 :(得分:2)

我发现当我重写内容或多人触摸一段代码时会发生这样的事情。看不出任何特别的原因。

我希望 i 在此块上方正确初始化。

答案 5 :(得分:0)

最简短,最诚实的答案很简短“只是因为”。 绝对没有实际的理由这样做,我们没有从这样的2微笑循环中获得任何利润。

至于上述原因,例如:

  • 重构 - 这是最有可能的,但不过这不是借口。
  • 缩小注意事项 - 更少,更少可能。
  • 心理/可读性/代码支持问题 - 我非常怀疑有人写这样的代码时要记住,用户可能会因某些代码构造和松散的注意力而感到困惑;
好吧,至于这些原因 - 所有这些都值得一提,但是,说实话,jquery代码风格并不理想。有时会出现 的原因,有时候,这只是事实。

生产代码并不总是最漂亮的代码。阅读任何语言的生产就绪,硬核代码始终是好的,但不是100%的代码风格。说,vim是漂亮的,非常强大的软件,但是(至于我)一些纯粹主义者可能会对它的源代码感到惊讶。虽然循环的东西是好的))))

答案 6 :(得分:0)

所以t至少会运行一次,因为如果你使用while循环,如果逻辑是假的,它就不会运行。对于lopp,即使它是假的,也会至少运行一次。