ブラウザは、ループを通過するたびに新しい nodeList オブジェクトをインスタンス化しますか、それとも、生成された単一のリストを毎回参照するだけですか。
getElementsByTagName
これは、2 つの呼び出しが同じオブジェクトを返すかどうかをテストすることで簡単にテストできます。
document.getElementsByTagName('div') === document.getElementsByTagName('div')
// true
このメソッドを同じ引数で呼び出すと、実際には同じオブジェクトが返されるようですNodeList
(少なくとも Firefox と Chrome では)。毎回新しいリストを生成するわけではありません。
したがって、ループ内で何度も呼び出しても違いはないと思うかもしれません。ただし、私が見ているように、リストを変数に格納する理由は複数あります。
各ループに不要な関数呼び出しがあります。
舞台裏で実際に何が起こっているかはわかりません。同じオブジェクトが返されても、リストがドキュメントの現在の状態を反映していることを確認するプロシージャが実行されている可能性があります。これは、関数を呼び出さなかった場合には発生しません。
最も重要なこと: DOM 仕様では、同じリストを返す必要がないようです。Firefox と Chrome (私がテストした場所) での動作は実装の詳細にすぎない可能性があるため、この動作には依存しません。実際、仕様では、新しいリストを返すことが明示的に述べられています。
戻り値: 一致したすべての要素を含む新しい NodeList オブジェクト。
nodeList オブジェクトを変数に格納し、必要に応じて参照する方がよいかどうか疑問に思っていました。
はい、そうです。getElementsByTagName
要素が追加または削除されたときに再度呼び出す必要はありません。これは、返さNodeList
れるものがliveであるためです。つまり、ドキュメントに加えられた変更は、明示的に更新することなく、リストに直接反映されます。
リストの へのアクセスなど、特定の操作length
によっても再評価がトリガーされます。したがって、リストを変数に保存することに加えて、長さもキャッシュすることができます。
var nodes = object.getElementsByTagName(tagName);
for (var index = 0, l = nodes.length; index < l; index++) {
nodes[index].property = value;
}
これは、必要なものに応じて、非常に便利または非常に混乱する可能性があります。関数が呼び出された時点で存在するノードのリストのみが必要な場合は、NodeList を配列に変換する必要があります。
var nodes = Array.prototype.slice.call(object.getElementsByTagName(tagName), 0);