DOM: NodeList vs HTMLCollection

By Xah Lee. Date: . Last updated: .

Difference Between NodeList, HTMLCollection

NodeList is a collection of nodes. Node includes any HTM/XML element, and also text content of a element, such as inner text of <p>…</p>.

HTMLCollection is a collection of HTM/XML elements.

Has ForEach or Iterable?

As of 2019-05-30, on Google Chrome, Safari, Firefox:

HTMLCollection vs NodeList, as of 2019-05-30
Interfacetrue arrayhas forEachiterable
HTMLCollectionnonoyes
NodeList noyesyes
HTMLCollection vs NodeList 2019-05-30 943mt
HTMLCollection vs NodeList, as of 2019-05-30. Both not true array. But one inherit forEach. Both inherit Symbol.iterator (so is iterable)
// print info of a object, see if they are true array, or iterable.
// version 2019-05-30
const ff = ((x) => {
console.log("Type is:", Reflect.apply ( Object.prototype.toString , x, [] ) );
console.log("is true array:", Array.isArray ( x ) );
console.log("has forEach:", Reflect.has ( x , "forEach") );
console.log("is iterable:", Reflect.has ( x , Symbol.iterator ) );
});

ff (document. getElementsByTagName("p"));
ff (document. getElementsByClassName("x"));
ff (document. getElementsByName("x"));

Iterable Object

• NodeList and HTMLCollection are iterable objects.

You can use for-of loop on them.

[see JS: for-of Loop]

Array-Like Object

• NodeList and HTMLCollection are array-like objects.

[see JS: Array-Like Object]

To use array methods on array-like object, call the method like this:

Array.prototype.forEach.call(elements, f)

[see JS: Function Call, Apply, Bind]

you can convert it to array by:

Array.from ( array_like_obj )

[see JS: Array-Like Object to Array]

Live Object or No?

• NodeList and HTMLCollection are NOT ALWAYS live objects. For example: document.querySelectorAll return a non-live object. [see DOM: Get Elements by ID, Tag, Name, Class, CSS Selector]

• There's no builtin way to find out whether NodeList or HTMLCollection is live object.

• When working with live objects, you must be careful, not to insert or remove element within a loop. [see DOM: What Does Live Object Mean?]

NEVER use for (var x in object) {…}, because that loops thru all enumerable properties and goes into prototype chain. [see JS: Access Property]

The most supported and safe and fast way to loop thru array-like object is a normal loop, like this:

for (let i = 0; i < myNodeList.length; ++i) {… myNodeList[i] …}

What Does getElementsByClassName Return?

As of 2019-05-30, on Google Chrome, Safari, Firefox:

HTMLCollection vs NodeList 2019-05-30 g4dt4
HTMLCollection vs NodeList 2019-05-30 g4dt4
// print if the DOM get element functions return node list or hmtl collection
[
"getElementsByTagName",
"getElementsByClassName",
"getElementsByName",
"querySelectorAll",
].forEach (((x) => {
let y = document[x] ("p");
console.log( `${x} → ${Reflect.apply ( Object.prototype.toString , y, [] )}`);
}));

As of 2013-04-26, getElementsByClassName in {Firefox, Internet Explorer} return HTMLCollection. {Chrome, Safari, Opera} return NodeList. Older versions of Firefox returns NodeList.

[see DOM: Get Elements by ID, Tag, Name, Class, CSS Selector]

As of 2016-07-02, getElementsByClassName in {Google Chrome, Firefox} returns HTMLCollection.

As of 2019-05-30, getElementsByClassName in {Google Chrome, Safari, Firefox} returns HTMLCollection.

How to Determine NodeList or HTMLCollection

You can find out the type by:

Object.prototype.toString.call (document. getElementsByClassName("xyz") )

It'll return a string like "[object HTMLCollection]" or "[object NodeList]".

[see JS: Determine Type of Object]

Even Browsers and W3C Are Confused

Here's what Mozilla says:

Note: While the W3C DOM 3 Core specification says elements is a NodeList that was simply because of a an attempt to have the “core” specification not depend on the “html” specification at that time. The DOM 4 draft says that elements is an HTMLCollection.

Gecko/Firefox currently returns a NodeList (Bug 162927) but starting with Gecko/Firefox 19, this method will return HTMLCollection (Bug 799464). Internet Explorer returns a HTMLCollection. WebKit returns a NodeList. Opera also returns a NodeList, but with a namedItem method implemented, which makes it similar to a HTMLCollection.

, from https://developer.mozilla.org/en-US/docs/Web/API/Element.getElementsByTagName

Here's WHATWG says as of 2016-07-02:

Elements is the better solution for representing a collection of elements. HTMLCollection is an historical artifact we cannot rid the web of.

DOM How-To


Web Scripting Overview


HTML Input


Web Scripting Examples


Web Scripting Misc


jQuery


node.js

Like it? Help me by telling your friends. Or, Put $5 at patreon.

Or, Buy JavaScript in Depth

If you have a question, put $5 at patreon and message me.

Web Dev Tutorials