DOM: NodeList vs HTMLCollection
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?
Interface | true array | has forEach | iterable |
---|---|---|---|
HTMLCollection | no | no | yes |
NodeList | no | yes | yes |

// 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.
Array-Like Object
NodeList and HTMLCollection are Array-Like Objects .
To use array methods on array-like object, call the method like this:
Array.prototype.forEach.call(elements, f)
[see Function Call, Apply, Bind]
you can convert it to array by:
Array.from(array_like_obj)
[see Array-Like Object to Array]
is Live Object?
• 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 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:
getElementsByTagName
return HTMLCollection.getElementsByClassName
return HTMLCollection.getElementsByName
return NodeList.querySelectorAll
return NodeList.

// 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 Determine Type of Object]
Even Browsers and W3C Are Confused
Here is 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 is 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.