過去および現在のほとんどのプロジェクトでは、次のようなforループを使用する傾向があります。
var elements = document.getElementsByTagName('div');
for (var i=0; i<elements.length; i++) {
doSomething(elements[i]);
}
「reverse while」ループを使用する方が速いと聞きましたが、これを確認する本当の方法はありません。
var elements = document.getElementsByTagName('div'),
length = elements.length;
while(length--) {
doSomething(elements[length]);
}
JavaScriptの要素、またはそれに関する配列をループ処理する場合、ベストプラクティスと見なされるものは何ですか?
これは私がよく使うループの素敵な形です。 forステートメントから反復変数を作成し、長さプロパティをチェックする必要はありません。長さプロパティは、NodeListを反復処理するときに特にコストがかかる可能性があります。ただし、注意する必要があります、あなたは配列内のいずれかの値が「偽」である可能性がある場合は使用できません。実際には、nullを含まないオブジェクトの配列(NodeListなど)を反復処理するときにのみ使用します。しかし、私はその構文糖が大好きです。
var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
for (var i=0, item; item = list[i]; i++) {
// Look no need to do list[i] in the body of the loop
console.log("Looping: index ", i, "item" + item);
}
これは、リストに['-1']
プロパティがない限り、逆方向にループするためにも使用できることに注意してください。
var list = [{a:1,b:2}, {a:3,b:5}, {a:8,b:2}, {a:4,b:1}, {a:0,b:8}];
for (var i = list.length - 1, item; item = list[i]; i--) {
console.log("Looping: index ", i, "item", item);
}
ES6アップデート
for...of
は名前を提供しますが、インデックスは提供しません。 ES6
for (let item of list) {
console.log("Looping: index ", "Sorry!!!", "item" + item);
}
場合によっては、needで逆順でループすることに注意してください(ただし、i--も使用できます)。
たとえば、誰かが新しいgetElementsByClassName
関数を使用して、特定のクラスの要素をループし、このクラスを変更したいと考えていました。彼は2つの要素のうち1つだけが変更されていることを発見しました(FF3で)。
これは、関数がライブNodeListを返すためです。このため、Domツリーの変更が反映されます。リストを逆順にたどることで、この問題を回避できました。
var menus = document.getElementsByClassName("style2");
for (var i = menus.length - 1; i >= 0; i--)
{
menus[i].className = "style1";
}
インデックスの進行を増やす場合、インデックス1を要求すると、FFはDomを検査し、元のDomの2番目であるstyle2の最初のアイテムをスキップし、3番目の初期アイテムを返します!
それはおそらく既知の宇宙で最も一般的なループ構造であり、逆ループが実際にあなたをいつでも救うとは思わないので(おそらく増分/デクリメントおよび各反復での比較)。
他の人が認識および読み取り可能なコードは間違いなく良いことです。
以前にdocument.getElementsByClassName()で非常によく似た問題がありました。当時、ノードリストが何であるかは知りませんでした。
var elements = document.getElementsByTagName('div');
for (var i=0; i<elements.length; i++) {
doSomething(elements[i]);
}
私の問題は、要素が配列になると予想していたことでしたが、そうではありませんでした。 Document.getElementsByTagName()が返すノードリストは反復可能ですが、array.prototypeメソッドを呼び出すことはできません。
canただし、次のようなノードリスト要素を配列に追加します。
var myElements = [];
for (var i=0; i<myNodeList.length; i++) {
var element = myNodeList[i];
myElements.Push(element);
};
その後、配列の要素で.innerHTMLや.styleなどを自由に呼び出すことができます。
私も簡単な方法を使用することをお勧めします(KISS!-)
-しかし、いくつかの最適化が見つかりました。つまり、配列の長さを複数回テストしません。
var elements = document.getElementsByTagName('div');
for (var i=0, im=elements.length; im>i; i++) {
doSomething(elements[i]);
}
Andrew Hedgesのテストに関する私のコメントも参照してください...
単純な反復、導入した最適化、および逆のdo/whileを比較するテストを実行してみました。ここでは、配列内の要素がすべてのループでテストされました。
そして、残念なことに、私がテストした3つのブラウザーの結果は非常に異なっていましたが、最適化された単純な反復はすべて最速でした!-)
500,000個の要素を持つ配列は、実際のテストの外側に構築され、反復ごとに特定の配列要素の値が明らかになります。
テストを10回実行します。
結果:
シンプル:984,922,937,984,891,907,906,891,906,906
平均:923.40ミリ秒。
最適化:766,766,844,797,750,750,765,765,766,766
平均:773.50ミリ秒。
逆実行/時:3375,1328,1516,1344,1375,1406,1688,1344,1297,1265
平均:1593.80ミリ秒。 (特に厄介な結果に注意してください)
結果:
シンプル:344,343,344,359,343,359,344,359,359,359
平均:351.30ミリ秒。
最適化:281,297,297,297,297,281,281,297,281,281
平均:289.00ミリ秒
逆do/while:391,407,391,391,500,407,407,406,406,406
平均:411.20ミリ秒。
結果:
シンプル:278,251,259,245,243,242,259,246,247,256
平均:252.60ミリ秒。
最適化済み:267,222,223,226,223,230,221,231,224,230
平均:229.70ミリ秒。
逆do/while:414,381,389,383,388,389,381,387,400,379
平均:389.10ミリ秒。
Juan Mendezによって提供されるループの形式は非常に便利で実用的です。少し変更して、false、null、ゼロ、空の文字列でも動作するようにしました。
var items = [
true,
false,
null,
0,
""
];
for(var i = 0, item; (item = items[i]) !== undefined; i++)
{
console.log("Index: " + i + "; Value: " + item);
}
私はあなたがそれを聞きたくないことを知っていますが、この場合、ベストプラクティスが最も読みやすいと思います。ここから月までループがカウントされない限り、パフォーマンスゲインは十分ではありません。
私はこの質問が古いことを知っています-しかし、これは別の非常に簡単な解決策です...
var elements = Array.from(document.querySelectorAll("div"));
その後、標準の配列のように使用できます。
読みやすいので、forループの方が好きです。長さから0へのループは、0から長へのループよりも効率的です。そして、あなたが言ったように、逆のwhileループを使うことはfoorループよりも効率的です。比較結果のあるページへのリンクはもうありませんが、ブラウザによって違いが異なることを覚えています。一部のブラウザでは、whileループが逆に2倍速くなりました。ただし、「小さな」配列をループしている場合は違いはありません。あなたの例の場合、要素の長さは「小さい」
2つの選択肢があると思います。 jQueryや同様のフレームワークなどのdom要素では、反復の良い方法を提供します。 2番目のアプローチはforループです。