JavaScriptのHTMLCollectionとNodeListの違いをあらためて確認してみよう

2024年 5月20日 Posted 野々瀨(フロントエンドエンジニア)

JavaScriptで複数の要素を取得する際、getElementsByClassNameメソッドやquerySelectorAllメソッドとさまざまなメソッドを使用して取得します。戻ってくる値は、HTMLCollectionNodeListというオブジェクトで返ってきます。しかし、同じまとまった形なのに使用するメソッドによっては、HTMLCollectionやNodeListと違いがあります。ここではどのような違いがあるのかを軽く説明したいと思います。

HTMLCollectionとは

HTMLCollectionは、複数の要素の集合体で、配列に似たオブジェクトです。また、一致した要素がDOM上に増加したり減少したりした場合にも動的に反映されます。

HTMLCollectionは次のメソッドやプロパティによって返されます。

HTMLCollectionは次のプロパティやメソッドを持ちます。

プロパティ名説明
length 要素の数を返す。

メソッド名説明
item 第一引数で指定したインデックス番号に一致する要素を取得する。
namedItem 第一引数で指定したname属性値に一致する要素を取得する。

参考リンク

NodeListとは

NodeListは、複数のノードの集合体であるオブジェクトです。ノードですので、タグ NodeListは動的に変化されるものと、静的に変化しないものの2種類があります。

NodeListは次のメソッドやプロパティによって返されます。

NodeListは次のプロパティやメソッドを持ちます。

プロパティ名説明
length ノードの数を返す。

メソッド名説明
item 第一引数で指定したインデックス番号に一致する要素を取得する。
entries キー(インデックス番号)とノードをペアとしたイテレーターを返す。
forEach ノードを一つずつ繰り返して、第一引数で指定したコールバック関数を実行する。
keys 全てのキー(インデックス番号)をイテレーターで返す。
values 全てのノードをイテレーターで返す。

参考リンク

得られる要素の違い

HTMLCollectionとNodeListとでは、得られる要素に違いがあります。HTMLCollectionはdivといった要素だけなのに対し、NodeListはテキストやdivといった要素を含むノード全てを対象にします。例えばElement.childrenプロパティとNode.childNodesプロパティで取得しますと、次のように戻り値が異なります。

<div class="foo">
	Lorem ipsum, dolor sit amet consectetur adipisicing elit. Suscipit nesciunt perspiciatis ab!
	<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Explicabo aut consequatur voluptatem?</p>
	<p>Lorem ipsum dolor sit amet consectetur adipisicing elit. Neque ut cupiditate modi.</p>
</div>
const parentElem = document.querySelector('.foo');

console.log(parentElem.children);
console.log(parentElem.childNodes);

繰り返すコードの違い

HTMLCollectionもNodeListもインデックス番号を持っていますので、配列のようにfor文を使用して繰り返すことができます。

const elems = document.getElementsByClassName('foo');

// for
for (let i = 0, len = elems.length; i < len; i++) {
	console.log(elems[i]);
}

// for of
for (const elem of elems) {
	console.log(elem);
}
const elems = document.querySelectorAll('.foo');

// for
for (let i = 0, len = elems.length; i < len; i++) {
	console.log(elems[i]);
}

// for of
for (const elem of elems) {
	console.log(elem);
}

NodeListでは、繰り返しが可能なforEachメソッドを持っています。

const elems = document.querySelectorAll('.foo');

elems.forEach(elem => {
	console.log(elem);
});

このようにHTMLCollectionは繰り返すメソッドが用意されていませんが、NodeListはforEachというメソッドが用意されています。HTMLCollectionでもコールバック関数で繰り返しを行いたい場合は、次のようにArray.fromメソッドを使用し、配列に変換することで可能になります。

const elems = document.getElementsByClassName('foo');

Array.from(elems).forEach(elem => {
	console.log(elem);
});

まとめ

まとめると、HTMLCollectionとNodeListとでは次のような違いがあります。