A pretty strange issue caused by HTML DOM's “querySelectorAll” method or “getElementsByTagName” method

StackOverflow https://stackoverflow.com/questions/11724551

Question

See codes:

<!DOCTYPE html>
<meta charset="utf-8">
<title>An HTML5 Document</title>
<p>
<p>
<script>
    var a = [1, 2],
        b = [3, 4],
        c = a.concat(b),
        d, e, f, g;

    console.log(c); // No problem

    d = [document.querySelectorAll('p')[0], document.querySelectorAll('p')[1]];
    e = a.concat(d);
    console.log(e); // No problem

    f = document.querySelectorAll('p'); // f = document.getElementsByTagName('p');
    g = a.concat(f);
    console.log(g); // Pretty strange...
</script>

jsFiddle: http://jsfiddle.net/V7gmE

My question is:

c.length is 4. No poblem. e.length is 4. No poblem.

If I use f = document.querySelectorAll('p'); or f = document.getElementsByTagName('p');, why g.length is '3'?

Thank you.

Was it helpful?

Solution

There is no problem, your third array is just [1, 2, NodeList].querySelectorAll returns a NodeList which in this case contains two elements. In the second example, you specifically take the first and second elements from the NodeList and put them into an array. While NodeLists may seem like arrays, they are not, and when you use the Array.concat method on it, the individual elements are not picked out.

From MDN:

NodeList are used very much like arrays and it would be tempting to use Array.prototype methods on them. This is, however, impossible.

Here is another example that might help get the point across: http://jsfiddle.net/radu/j5gvy/1/

var a = [1, 2],
    obj = { 0 : '', 1 : ''},
    b = [obj[0], obj[1]];

c = a.concat(obj);

console.log(c.length); // 3

d = a.concat(b);

console.log(d.length); // 4

Just because I define an object that can be accessed like an array does not make it an array.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top