0

I am JS newbie reading about JS data types which pointed me to the Live NodeLists and Static NodeLists on those pages: Why is getElementsByTagName() faster than querySelectorAll()? and HTMLCollections & NodeLists Mentioned pages describes their differences using very similar examples:

Live NodeLists:

var divs = document.getElementsByTagName("div"),
    i=0;

while(i < divs.length){
    document.body.appendChild(document.createElement("div"));
    i++;
}

Static NodeLists:

var divs = document.querySelectorAll("div"),
    i=0;

while(i < divs.length){
    document.body.appendChild(document.createElement("div"));
    i++;
}

I am interesting in this particular piece of code:

var divs = document.getElementsByTagName("div"),
    i=0;

resp. this one:

var divs = document.querySelectorAll("div"),
    i=0;

Can somebody please clarify me what is this construction doing? Or the question maybe should be: what is the content and type of variable divs after this? I was assuming that this is array, so I have tried this minimalistic JS vhere I have added further variables:

var divs = document.getElementsByTagName("div"), 
    j=5,   
    i=0;
alert(divs.length);

but no mather how many other variables I have added to divs along with document.getElementsByTagName the result of alert() was always 1. Then I have tried print it via typeof() and it returns me that this is object. What is going on here, is it some special JS syntactic sugar or what?

Wakan Tanka
  • 5,906
  • 11
  • 47
  • 96
  • 1
    [Comma operator(,) Where it can “really” be useful](http://stackoverflow.com/q/9579546/1169798). It seems you do not know the comma operator. – Sirko Nov 07 '13 at 15:51
  • 1
    You typed the answers to your question as the bolded headers before the code samples :) They're NodeList objects, either live or static.' – Pointy Nov 07 '13 at 15:51
  • 1
    @Sirko well in a `var` statement, the comma isn't *really* the "comma operator" from the expression grammar. Splitting hairs perhaps. – Pointy Nov 07 '13 at 15:53
  • don't use alert... use `console.log(variable)` – gloomy.penguin Nov 07 '13 at 15:53
  • @gloomy.penguin uh, why? – Mathletics Nov 07 '13 at 15:55
  • because you can see the whole element if you want? you can see more without converting anything to a string.....? you can see exactly what something contains and if you convert elements to strings first the might look the same when they aren't? i dunno... from the comma link in the first comment... [this answer](http://stackoverflow.com/a/9579588/623952) deals with the OP's question directly – gloomy.penguin Nov 07 '13 at 15:56
  • @gloomy.penguin I'm aware of the benefits of using `console.log` but here OP is just looking at an int. _Don't do x_ comments aren't really helpful to beginners without an explanation of _why_. – Mathletics Nov 07 '13 at 16:00
  • [Why is console.log() considered better than alert()?](http://stackoverflow.com/questions/8203473/why-is-console-log-considered-better-than-alert) – gloomy.penguin Nov 07 '13 at 16:00
  • 1
    @Mathletics The primary reason not to use `alert` for debugging is that it halts code execution, which can screw up the order of things when working with asynchronous functions. There are also some event handlers that get fired again when you dismiss the alert, resulting in a potential loop where you just keep getting a new alert when trying to get rid of the current one. – Anthony Grist Nov 07 '13 at 16:00
  • @Mathletics: alert can make issues that aren't there... just by "observing" something. it changes focus for elements... you can get a weird loop that wouldn't happen if you just did a `console.log()`. (i've had it happen before). It was just a comment to OP... just a suggestion. If they're asking these kind of questions, they're willing to learn and try things. I just thought they should look into it. If you prefer alert, that's cool. It was just a suggestion. – gloomy.penguin Nov 07 '13 at 16:02
  • @AnthonyGrist and gloomy.penguin, thank you, that is exactly what I wanted you to convey to the OP. – Mathletics Nov 07 '13 at 16:04
  • @Mathletics: you didn't say any of those things... lol...? you were talking to me, not OP, too. I don't think explaining `console.log()` to OP was a priority at all in your initial comment. You said "uh, why?" to _me_. – gloomy.penguin Nov 07 '13 at 16:06
  • @gloomy.penguin it was in [my follow up](http://stackoverflow.com/questions/19840340/javascript-please-explain-this-syntax?noredirect=1#comment29504210_19840340), but no matter. All worked out in the end! :) – Mathletics Nov 07 '13 at 16:36

2 Answers2

2
var divs = document.getElementsByTagName("div"),
i=0;

is the same as

var divs = document.getElementsByTagName("div");
var i=0;

You can declare multiple variables with a single var by using a comma-separated list.

Mathletics
  • 31,135
  • 5
  • 47
  • 57
0

This code:

var divs = document.getElementsByTagName("div"), 
    j=5,   
    i=0;

Is the same as this:

var divs = document.getElementsByTagName("div");
var j=5;
var i=0;

It creates 3 variables:

  1. Variable div containing all div elements on the page
  2. Variable j containing the value 5
  3. Variable i containing the value 0

The reason typeof returns 'object' is because the typeof operator in JavaScript is messed up. It simply returns 'object' for most object-based entities, which include Arrays and NodeLists.

To answer your original question, both the return value from document.getElementsByTagName and document.querySelectorAll are NodeList. This means you will not be able to mutate them, unlike arrays. Furthermore, the value returned by document.getElementsByTagName is a live node list, which means it always reflects the current state of the DOM.

To clarify:

var liveNodeList = document.getElementsByTagName('div');
var nodeList = document.querySelectorAll('div');
console.log(liveNodeList.length, nodeList.length); //Should output the same value twice
document.body.appendChild(document.createElement('div')); //Add a new div to the DOM
console.log(liveNodeList.length, nodeList.length); //Now, the live node list length should be one more since it updated to reflect the DOM state

try{
    nodeList.push('test');
}catch(e){
    console.log('NodeLists may not be mutated');
}
Borre Mosch
  • 3,584
  • 1
  • 16
  • 28