Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Loops, Arrays and Objects Tracking Multiple Items with Arrays Using For Loops with Arrays

Michelle Harrison
Michelle Harrison
8,782 Points

I did mine differently

I tried doing this before watching how he did it to see if I could do it on my own. This is what I wrote:

var songs = [
'We Can Try', 
'Spain', 
'The One Thing', 
'Move', 
'Changed By You'];

for(var i = 0; i < songs.length; i += 1){
    var html = "<li>" + songs[i] + "</li>";
}

document.write("<ol>" + html + "</ol>");

When I load it, only the last song title "Changed by You" comes up in the list. Why? My for loop is the same as Dave's so I don't understand why this isn't working. If someone can help that would be great because personally, I like my way better than Dave's....you know, if it worked and all.

****Edit*** I figured it out, It was a scope thing. I had problems with the same thing earlier today; I keep thinking I understand it and then...oh no just kidding try again.

var html = " ";
for(var i = 0; i < songs.length; i += 1){
    html += "<li>" + songs[i] + "</li>";
}


document.write("<ol>" + html + "</ol>");

It was a simple matter of defining the variable 'html' outside of the loop. I'm assuming since it's being used outside of the loop then it has to be defined outside of the loop as well? Is that correct?

Also, I'm finding my code much simpler than the one Dave wrote up. Is it okay to use this one or does a program like this have to be done specifically the way he did it?

2 Answers

Ginger Cullen
Ginger Cullen
4,301 Points

It's not a scope issue. You can use html outside the loop. Even before the loop! That's because JavaScript has function scope and variable hoisting. Function scope here means that the for loop does not have it's own local scope. Variable hoisting means that variables are moved to the top of the scope. Here, this means that all your variables are moved to the top of your program and are available for use anywhere in your program. (That's because you have no functions and only one scope - the global scope.)

So, your first program really looks something like this:

var songs, i, html; // values set to undefined
songs = ['We Can Try','Spain','The One Thing','Move','Changed By You'];
for(i = 0; i < songs.length; i += 1){
    html = "<li>" + songs[i] + "</li>";
}
document.write("<ol>" + html + "</ol>");

The problem here is that you are using = and not +=. Each time through the loop, you are overwriting whatever html contains with a new string.

  • 1st time through the loop: i = 0, html = "<li>We Can Try</li>"
  • 2nd time through the loop: i = 1, html = "<li>Spain</li>"
  • ...
  • 5th time through the loop: i = 4, html = "<li>Changed By You</li>"
  • Then, i is incremented to 5 which is not less than the length of songs, so the loop ends
  • When document.write is executed: i = 5, html = "<li>Changed By You</li>"

Of course, I'm sure you discovered that you can't write this:

for(var i = 0; i < songs.length; i += 1){
    var html += "<li>" + songs[i] + "</li>";
}

You'll get a syntax error.

And this won't quite work either:

for(var i = 0; i < songs.length; i += 1){
    var html;
    html += "<li>" + songs[i] + "</li>";
}

That's because += is the equivalent of this code: html = html + "<li>" + songs[i] + "</li>". The first time through the loop, html starts out as undefined, so you are concatenating your list of songs to "undefined". Thus, your final program is indeed the correct way to fix your code.

Finally, Dave is using functions here for 2 main reasons:

  1. For code reuse. Suppose you have a bunch of lists of songs to display. A function would be good here where you could pass each list to your function.
  2. To limit scope. For loops don't have their own scope, but functions do. Dave's listHTML variable is only available inside his function printList.

Great answer +1

The reason var html is defined outside of the for loop, is because if you define it inside the loop, the html variable is being 'overwritten' each time the loop goes round.

Each time around the for loop you are re-declaring the html variable (by using the var keyword). So by the time it reaches the end of the loop, html will only contain 1 song.

In the 2nd example, the html variable is declared outside the loop (var html = ...), then referenced inside it (html += ...).

It is also using +=, which adds an item to the html variable. Using = sets the html variable equal to an item.

= means X = Y;

+= means X = X + Y;

See Assignment Operators


Here's what happens at each stage of the loop, for the 2 examples you posted. I added a console.log which will show the value of the html variable, each time around the loop.

Example_one.js
var songs = [
'We Can Try', 
'Spain', 
'The One Thing', 
'Move', 
'Changed By You'];

for(var i = 0; i < songs.length; i += 1){
    var html = "<li>" + songs[i] + "</li>";
    console.log( i + ": " + html);
}

document.write("<ol>" + html + "</ol>");

// 1st time around the loop var html is equal to: <li>We can Try</li>

// 2nd time: <li>Spain</li>

// 3rd time: <li>The One Thing</li>

// 4th time: <li>Move</li>

// 5th time: <li>Changed By You</li>


Example_two.js
var songs = [
'We Can Try', 
'Spain', 
'The One Thing', 
'Move', 
'Changed By You'];

var html = " ";
for(var i = 0; i < songs.length; i += 1){
    html += "<li>" + songs[i] + "</li>";
    console.log( i + ": " + html);
}

document.write("<ol>" + html + "</ol>");

1st time around the loop var html is equal to: <li>We Can Try</li>

2nd time: <li>We Can Try</li><li>Spain</li>

3rd Time: <li>We Can Try</li><li>Spain</li><li>The One Thing</li>

4th time: <li>We Can Try</li><li>Spain</li><li>The One Thing</li><li>Move</li>

5th time: <li>We Can Try</li><li>Spain</li><li>The One Thing</li><li>Move</li><li>Changed By You</li>


Also if we try to use the += operator and declare the variable in the loop. We get an error:

for(var i = 0; i < songs.length; i += 1){
    var html += "<li>" + songs[i] + "</li>";
    console.log( i + ": " + html);
}

// Uncaught SyntaxError: Unexpected token +=

There are an unlimited amount of ways to build a program like this, you should write code whatever way feels best for you. Feel free to use however much or little of the code from the courses as you like. Breaking stuff is encouraged.

Hope this helps :)