3

バックグラウンド:


ノード リストを操作しているときに、非常に奇妙な現象に遭遇しました。getElementsByClassName などを使用して並べ替えたいと思いました。ノードリストを繰り返し処理し、各項目を配列にプッシュして配列をソートする方法が 1 つあります。(ちなみにこれは機能しましたが、期待どおりではありませんでした)。を使用しfor (var i in nodeList)て反復しようとしましたが、未定義の最後のいくつかの項目で例外をスローし続けました。奇妙な部分は、代わりfor (var i = 0; i < nodeList.length; i++)に反復処理に使用できることです。もう一度テストしたところ、stackoverflow ページでコンソールで次のコードを実行しました。

for (var i in document.getElementsByTagName("span"))
    console.count("items");
console.log(document.getElementsByTagName("span").length);

まで数えましたitems: 382が長さは380でした。予想通り、私が入ったときdocument.getElementsByTagName("span")[380]document.getElementsByTagName("span")[381]彼らは未定義で戻ってきました。この奇妙な動作は配列では発生しません (確かに、nodeLists と配列は異なりますが、これは問題の原因となっているループの違いではないことを証明しています)。

質問:


for(var i in nodeList)最後にいくつかの未定義の項目を返す nodeLists で構成要素の動作が異なるのはなぜですか?

4

2 に答える 2

4

for in反復ステートメントがキャッチする2つの追加プロパティは次のとおりです。

  • 長さ
  • アイテム

簡単な例を挙げましょう。ページに3つのSPAN要素があるとしましょう。

var spans = document.getElementsByTagName( 'span' );

これで、5つのプロパティをspans含むNodeListオブジェクトになります。

  • 0
  • 1
  • 2
  • 長さ
  • アイテム

最初の3つのプロパティはインデックスであり、それらのSPAN要素への参照が含まれています。他の2つのプロパティ(長さとアイテム)は、2つの追加のプロパティです。すべてのNodeListオブジェクトには、これら2つのプロパティがあります。

このステートメントは、 NodeListfor inオブジェクトの5つのプロパティすべてを繰り返し処理しますが、これはおそらく必要なものではありません。したがって、通常のステートメントを使用してください。for

var i, span;

for ( i = 0; i < spans.length; i++ ) {
    span = spans[i];
    // do stuff with span
}
于 2011-09-16T21:47:49.017 に答える
2

for-inは、長さやアイテムなど、オブジェクトのすべての列挙可能なプロパティを反復処理します (これがあなたの状況です)。ここからさらに 2 つの結果が得られます。また、オブジェクト プロトタイプに追加されたすべてを列挙します。

forは数値インデックスをループし、列挙可能なプロパティを考慮しません。そのため、以前の方法を使用する方がはるかに信頼性が高くなります。

于 2011-09-16T21:52:47.660 に答える