12

私は最近、Javascriptの配列を介してループする別の方法に出くわしました。

私は次のようなループを書いていました:

for (var len = 0; len < testData.length; len++) {
  total = total + testData[len];
}

私はそれをこのようにしたいくつかのコードを読みました:

for (var len = 0; testData[len]; len++) {
  total = total + testData[len];
}

これらがどのように機能するのか疑問に思っていたので、jsPerfを使用して調べました。結果はかなり素晴らしいです。2番目の方法は最初の方法よりも少し速いと思っていましたが、実際にははるかに高速です。

私がここで見逃している欠点はありますか?または、これはリストのアイテムをループするための最良の方法です。

アップデート:

灰色の状態が来ており、Diodeはテストケースの単純な欠陥を指摘しました。

間違いを訂正した後、これが最速です。

var datalen = testData.length;
for (var len = 0; len <datalen; len++) {
     total = total + testData[len];
}

アップデート2:

さらにいくつかのブラウザでテストした後、このテストケースは再び別の方向に進みます。ChromeとOperaでのみ、通常のforループが最速です。他のすべてのブラウザでは、 Shmiddtyの方法は少し高速です。

var i = testData.length, sum=0;
while (i--){
    sum += testData[i];
}
4

6 に答える 6

13

私は最初の形式がより良いと主張したいと思います。2番目の形式にはいくつかの問題があります。値を含むスパース配列がある場合はどうなりfalsyますか?好き:var testData = [ "text", undefined, false, 0, 5 ];

また、最初のフォームのパフォーマンスが向上することを期待しています。特に、Likesoの値を「キャッシュ」する場合testData.length

var i, len = testData.length;
for (i = 0; i < len; i += 1) {
  total = total + testData[i];
}
于 2012-09-10T18:32:02.500 に答える
4


更新:私は間違っていました、forEach非常に遅いです!ループの方が良いようです


forEachECMAScript第5版で定義されているを使用する必要があります。

testData.forEach(function(val,i,arr){
    total += val;
});

引数は次のとおりです。

  • val現在の値です
  • i現在のインデックスです
  • arr配列です

それらすべてを使用する必要はありません。

testData.forEach(function(val){
    total += val;
});

また、それをサポートしていないブラウザの場合は、このシムを使用できます。

if(!Array.prototype.forEach){
    Array.prototype.forEach = function(fn, scope) {
        for(var i = 0, len = this.length; i < len; ++i) {
            fn.call(scope || this, this[i], i, this);
        }
    }
}

詳細については、 Array.forEachを参照してください。

于 2012-09-10T18:34:22.707 に答える
3

次のようなループを実行することもできます。

var i = testData.length;

while (i--){
    console.log(testData[i]);
}

配列を逆方向にトラバースすることに注意してください。

または、要約すると:

var i = testData.length, sum=0;

while (i--){
    sum += testData[i];
}
于 2012-09-10T18:48:31.143 に答える
2

Shmiddtの答えに基づいて、逆方向のループを使用できます。Firefoxでは少し後ろ向きになり、Chromeでは次のようになります。

var total = 0;
for (var len = testData.length-1; len >=0; len--) {
  total += testData[len];
}

テスト: http: //jsperf.com/for-until-length-vs-until-undefined/10

于 2012-09-10T19:32:12.883 に答える
1

パフォーマンスに関してはtestData[len]、要素が定義されているかどうかをチェックするだけで、null / false / "falsish"ではありません。これは、比較よりも高速であり、特に各反復でtestData.lengthを取得します。

したがって、2番目の方法は高速ですが、信頼性は高くありません。FritsvanCampenが正しく述べているように。

于 2012-09-10T18:34:03.177 に答える
1

セットアップコードは0を挿入します。これにより、最初の条件でループが中断します。

var testData = [];
for (var i = 0; i < 1000; i++) {
  testData.push(i);  // pushes 0 to `testData`
}


for (var len = 0; testData[len]; len++) {   // loop breaks on first condition-check as testData[0] is 0.
  total = total + testData[len];
}

以下のようにセットアップコードを変更して、違いを確認してください

var testData = [];
for (var i = 0; i < 1000; i++) {
  testData.push(i+1);
}

http://jsperf.com/for-until-length-vs-until-undefined/6

于 2012-09-10T18:49:24.657 に答える