- ベストアンサー
HTMLCollectionとNodeListの違いとは?
- HTMLCollectionとNodeListは、JavaScriptのDOM操作におけるノードのリストを表すオブジェクトです。
- JavaScriptとDOMは異なる概念であり、JavaScriptはECMAScriptに基づき、DOMはDocument Object Model Level Specificationに基づいています。
- HTMLCollectionはノードのリストを表し、NodeListとの違いはブラウザによって返す型が異なることです。FirefoxやIEではHTMLCollection型のオブジェクトが返される一方、Google ChromeやOperaではNodeList型のオブジェクトが返されます。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
HTMLCollection ブラウザが実装している DOM API の型で「生きて」いる順序付の連想配列 DOM が必要とする最低限の機能しかない 例: document.forms[0] 例: document.forms['x'] // <form name='x'> NodeList ブラウザが実装している DOM API の型で「生きて」いる配列、連想はできない DOM が必要とする最低限の機能しかない 例: document.body.childNodes 例: document.querySelectorAll('img') // 例外的に生きてない Array JavaScript の型で、配列を表す 内蔵型なので動作が高速、かつ多機能 上記二つは「生きて」いるオブジェクトの型です。 つまりDOMを操作すると、即座にオブジェクトにも反映されてしまいます。 例: <form>要素を追加する → document.forms の数が増える 一般的に「生きて」いるオブジェクトは、処理しづらくアクセス性能も悪いので、 配列内容を Array 型のオブジェクトに投影して「生きて」ない配列にします。 例: Array.prototype.slice.apply(document.getElementsByName('hoge')).forEach(function(e){}) 余談ではありますが、 DOM API は特定言語に依存しない仕様ですので、各言語ごとに実装があります。 ただ仕様書の付録として Java/ECMAScript の実装例があるぐらいこの二つの言語で多用されますので、 単純にDOMで検索すると Java の機能だと誤解するかもしれません。 JavaScript のほうを調べるなら、こちらをオススメします。あまり邦訳されていないのが欠点ですが。 https://developer.mozilla.org/ja/
その他の回答 (1)
- b0a0a
- ベストアンサー率49% (156/313)
・リンク先に「DOMのノードリスト(HTMLCollectionやNodeList)の配列化」という記述があるのですが、意味が分からないので、教えてください NodeList等はJSのArrayを継承していないので、配列のメソッドが使えず、扱うに不便なことがよくあります。 JSの配列操作のメソッドは、制限が緩いので、いくつかは配列のようなオブジェクトに対しても適応可能です。 それを利用して、配列をコピーして新しい配列を作るメソッドを、NodeList等に適応すれば、純粋な配列に変換できることが期待できます。 ただ、コピーするメソッドというものはないので、複製して変化を起こすメソッドを、変化を起こさないよう指定して代わりに使います。 例えば、sliceメソッドに何も渡さない、arr.slice()は、arrをコピーすると同等の働きをします。 ただ、NodeList等は配列のメソッドをもってないので、関数を大元のArray.prototype.sliceから持ってきて、callでthis(処理対象)を挿げ替えます。 arr.slice()はArray.prototype.slice.call(arr)と書けるように、Array.prototype.slice.call(list)とすることで、listに対してsliceメソッドを適応でき、結果NodeList等を配列化することができます。 ・そもそも「JavaScript」と「DOM」は異なる概念 ・JavaScript… ECMAScriptに基づく ・DOM … Document Object Model Level Specificationに基づく DOMは、仰るとおりJSとは分離されていて、JSに対しAPIが提供されている形になりますが、なんだかんだ言って今も昔もJSを一番重視しており、完全に別物とも言い切れません。 そもそも「JavaScript」という言葉自体の定義が「ECMAScript」や「DOM」に比べてあやふやです。 ECMAScript+DOM≒JavaScriptという見かたがされる時も多くあります。 ・JavaScript … 「オブジェクト型」「プリミティブ型」に分類可能 ・DOMオブジェクト … JavaScriptオブジェクトとは等価でない? オブジェクトはオブジェクトですが、区別しようと思えばいろいろできます。 例えば今までは「ネイティブ」と「ホスト」という分け方がよく使われてきました。 語感でなんとなく意味はわかると思いますが、ESで定義されてなくて、ホスト環境で提供されるDOMオブジェクトは「ホスト」オブジェクトです。 また、最近では「ネイティブ」と「ホスト」は「一般的」と「特殊」という用語に置き換わっています。 何の事はないですが、DOMは「特殊」なオブジェクト、ただそれだけです。あまり深く考える必要はありません。 ・NodeList … JavaScript配列オブジェクトとは等価でない? ・外見上は同じに見える「NodeList」「配列オブジェクト」判断の方法は? 前後の文脈から? ・HTMLCollectionとNodeListとの違いは? NodeListとHTMLCollectionは微妙に異なりますが、あまり深く考えず、NodeListの方をメインとして、両者同じものとして考えていいです。 この2つについて知っておかないといけないことは、Arrayを継承していないので、配列のメソッドを使えない残念仕様ということだけです。 JSには今まで、仕様上外部からArrayを正当に継承出来なかったりしたので、このようなややこしい配列もどきが生まれたわけですが、ES6になってその部分が克服されたので、後に述べるように改善されようとしています。 ・リンク先は関係あるでしょうか? なぜオラクル? Java版のDOM実装仕様のページです。 ・もしかしてブラウザによって返す型が異なるのでしょうか? そうであったりそうでなかったりします。 気にせず、気にしないといけないようなことをしないのが一番です。 ・結局「HTMLCollection型」「NodeList型」どちらが正しいのでしょうか? あるいは同じ意味? 2つともありますが、同じようなものです。 また、新しい仕様では、両者はArrayを正統に継承したElementsに一本化されることにもなりました。 既存のNodeList/HTMLCollectionが置き換えられることはありませんが、今後追加されるAPIではElementsが使われることになります。 つまり来年辺りからは3種類を扱っていかなければならなくなるわけですが、真APIはほとんどのケースで旧APIをより良く置き換えられるものなので、NodeList/HTMLCollectionを徐々に見なくて済むようになっていくとは思います。 また、既存のNodeListをArrayを継承させるよう仕様変更しようとする計画もありますが、これは実際テストしてみて既存のスクリプトで問題が出ないかどうかによるでしょう。
お礼
回答ありがとうございました。 >今まで、仕様上外部からArrayを正当に継承出来なかったりしたので、このようなややこしい配列もどきが生まれたわけですが、ES6になってその部分が克服されたので、後に述べるように改善されようとしています ・「配列もどき」という表現が分かりやすかったです >来年辺りからは3種類を扱っていかなければならなくなるわけですが、真APIはほとんどのケースで旧APIをより良く置き換えられるものなので、NodeList/HTMLCollectionを徐々に見なくて済むようになっていくとは思います ・初めて知りました ・この辺り勉強したほうが良いかな、と思っていたのですが、そういう事情なら他の方を優先的に見ていきたいと思います ・大変参考になりましたー
お礼
回答ありがとうございました。 >「生きて」いるオブジェクトの型です。 >つまりDOMを操作すると、即座にオブジェクトにも反映されてしまいます。 >一般的に「生きて」いるオブジェクトは、処理しづらくアクセス性能も悪いので、 >配列内容を Array 型のオブジェクトに投影して「生きて」ない配列にします ・この説明大変分かりやすかったです >DOM API は特定言語に依存しない仕様ですので、各言語ごとに実装があります ・初めて知りました ・びっくりしました ・大変勉強になりましたー