for循环而不是while循环

Ran*_*lue 54 jquery

通过jQuery源读取我偶然发现了以下代码(可在此处获得):

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

为什么for这里使用循环而不是while循环?

aro*_*oth 44

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

while (i < length && callback.apply(object[i], args)) {
    i++;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

  • 严格的`false`测试是必要的,因为那是*one*返回值会破坏迭代. (4认同)
  • @Jordi - 原始代码在循环执行后返回,而不对`i`进行任何额外的引用,并且`i`在本地作用于该函数.因此,出于所有实际目的,它们是相同的.在这种情况下,没有理由关注循环终止后`i`的值. (3认同)
  • 不过,代码并不等同.如果循环因为回调返回false而中断,那么`i`将比原始代码少一个. (2认同)

Ste*_*sen 26

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


ham*_*mar 21

这是引入这种奇怪的提交.

提交消息:

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 )
Run Code Online (Sandbox Code Playgroud)

似乎作者只是错过了将其for变为a 的机会while.


Bri*_*y37 6

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

for(;<condition>;){}
while(<condition>){}
Run Code Online (Sandbox Code Playgroud)

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

例如,这是原始代码的一部分.正如您所看到的,在此代码中,您可以始终保持"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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

将此与用a替换第二个循环进行比较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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)