Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript JavaScript Loops, Arrays and Objects Simplify Repetitive Tasks with Loops The Refactor Challenge Solution

David Beczuk
David Beczuk
2,430 Points

I don't get it. Can someone please tell me why does this code run in an infinite loop?

/***********************************
    Variable declarations
***********************************/
var html = '';
var red;
var green;
var blue;
var rgbColor;

/***********************************
 FOR Loop that generates the
 colored Nodes
***********************************/
for (i = 0; i < 10; i++) {
  rgb = getColor();
  rgbColor = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
  html += '<div style="background-color:' + rgbColor + '"></div>';
} // this loop seems to run just fine without the function call

/***********************************
 RGB value generator function
***********************************/
function getColor() {
  var ret = new Array();
  for (i = 0; i < 3; i++) {
     ret[i] = Math.floor(Math.random() * 256 );
  }
  return(ret);
}

/***********************************
    OUTPUT
***********************************/
document.write(html);

3 Answers

Matt F.
Matt F.
9,518 Points

Hi David,

You need to put the var declaration in front of the i = 0 in your function getColor.

Without it, the i variable will affect the global scope. This means that your for loop that you intend to iterate 10 times will iterate infinitely. This is because every time that for loop calls getColor, i is getting reset to 0.

With the var in front of the i = 0 inside the getColor function, that assignment of the value 0 will affect a new local variable scoped to that instance of getColor, instead of the global i value.

Change your code to this:

/***********************************
    Variable declarations
***********************************/
var html = '';
var red;
var green;
var blue;
var rgbColor;

/***********************************
 FOR Loop that generates the
 colored Nodes
***********************************/
for (var i = 0; i < 10; i++) {
  var rgb = getColor();
  rgbColor = 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')';
  html += '<div style="background-color:' + rgbColor + '"></div>';
  console.log(i);
} // this loop seems to run just fine without the function call

/***********************************
 RGB value generator function
***********************************/
function getColor() {
  var ret = new Array();
  for (var i = 0; i < 3; i++) {
     ret[i] = Math.floor(Math.random() * 256 );
  }
  return(ret);
}

/***********************************
    OUTPUT
***********************************/
document.write(html);

Here is a link to a Stack Overflow thread that goes into more detail:

http://stackoverflow.com/questions/5373278/variable-shadowing-in-javascript

Julie Myers
Julie Myers
7,627 Points

Just to add to what Matt said...

/*
for loops have no scope of their own. So, when you just have a for loop
in the global scope i will be registered in the global scope whether you have var
in front of it or not. For example:
*/
for(i = 0; i < 3; i++) {
  console.log(i);
  console.log(window.i);
}
// 0, 1, 2
// 0, 1, 2

for(var i = 0; i < 3; i++) {
  console.log(i);
  console.log(window.i);
}
// 0, 1, 2
// 0, 1, 2

/*
If you put the for loop inside of a function variable scoping rules still take effect.
In other words if you do no put the keyword var in front of i, when the function
is called i will be registered in the global scope. However, if you do put var keyword
in front of i, when the function is called i will be registered inside of the functions
scope. For example:
*/
function testingI() {
  for (i = 0; i < 3; i++) {
   console.log(i);
  }
}
testingI(); //0, 1, 2
window.i; // 3

function testingI() {
  for(var i = 0; i < 3; i++) {
    console.log(i);
  }
}
testingI(); //0, 1, 2
window.i; // Uncaught ReferenceError: i is not defined(…)
David Beczuk
David Beczuk
2,430 Points

Thank you guys. Made total sense. I knew how global variables act and yet I did not spot my missing local scope declaration of the i variable.

And thank you both for the detailed explanation.