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
Bryan Valencia
Full Stack JavaScript Techdegree Student 4,733 PointsEither array iteration or string conversion problem
So all I am trying to do is get an average of 9 values and display them to the user. For now, I am using pop up windows (alert and prompt). When I hit run, my program runs and I input 9 values. However, at the end of the program, the alert window displays, "NaN". I thought wrapping the prompt() in a parseFloat() would fix it but it hasn't (I want the number displayed to be a float btw). Can anyone help out?
var i;
var itemList = [];
itemList = ["prim", "spec", "heavy", "ghost", "helm", "chest", "legs", "class item", "artifact"];
for (i = 0; i < itemList.length; i++) {
var lightLevel;
var itemLight = parseFloat(prompt("Enter Light level for " + itemList[i] + ": "));
lightLevel += itemLight;
}
var averageLight = lightLevel / 9;
alert("Light level is currently: " + averageLight);
3 Answers
Steven Parker
243,658 PointsI notice a couple of issues:
- you're incrementing an unitialized variable (lightLevel)
- you're referencing that same variable outside the scope where it was created
Try moving the definition of lightLevel outside the loop and give it a starting value:
var i;
var itemList = [];
itemList = ["prim", "spec", "heavy", "ghost", "helm", "chest", "legs", "class item", "artifact"];
var lightLevel = 0;
for (i = 0; i < itemList.length; i++) {
var itemLight = parseFloat(prompt("Enter Light level for " + itemList[i] + ": "));
lightLevel += itemLight;
}
var averageLight = lightLevel / 9;
alert("Light level is currently: " + averageLight);
Shawn Denham
Python Development Techdegree Student 17,802 Points@Steven Parker can you explain why moving lightLevel outside the loop worked? I am not sure what I did but nothing would work for me until I set the initial value of lightLevel and lightItem to 0.0.
Shawn Denham
Python Development Techdegree Student 17,802 PointsIt seem that if you don't set lightLevel equal to 0 to start it will return NaN. I have been looking though MDN and cannot figure out why.
Jason Anello
Courses Plus Student 94,610 PointsSteven,
javascript does not have block level scope. It only has global and function level scope.
So even if the variable is declared inside the loop, the declaration is hoisted to the top of either the global code or the top of the function if this code is within a function. It's a best practice to declare variables at the top but doing it inside the loop wouldn't cause any issues.
The following code runs perfectly fine but not a good practice since you're relying on the hoisting instead of being explicit about it.
lightLevel = 0;
for (var i = 0; i < 10; i++) {
var lightLevel;
lightLevel += 5;
}
console.log(lightLevel); // 50
I think the only issue was the uninitialized variable.
Shawn,
lightLevel is undefined the first time lightLevel += itemLight; is reached. It's been declared but hasn't been given a value yet.
You're trying to do something like lightLevel = undefined + 5.0; the first time through the loop. This results in NaN being assigned to lightLevel
Next time through the loop you have something like lightLevel = NaN + 3.0 Any calculations with NaN continue to result in NaN. lightLevel is therefore stuck at NaN for the rest of the loop.
Shawn Denham
Python Development Techdegree Student 17,802 PointsAwesome! Thanks Jason!
Steven Parker
243,658 PointsAs I understand it, "hoisting" is only applied to function declarations, not to variable declarations.
Jason Anello
Courses Plus Student 94,610 PointsHey Steven,
Are you getting to some old notifications here? :)
I'm pretty sure that you do have variable hoisting with the var keyword at least. This doesn't apply anymore with let and const
I don't know if you had a chance to try the code in my comment but I don't think it would be able to log 50 if there was block level scope. In my example, if you replace the var keyword with let then you'd have 2 lightLevel variables. A global one and one local to the loop.
In that case, it logs 0.
The same thing happens with the index variable even though I used the var keyword in the for statement. You could log the value of i after the loop and it would be 10. What's happening behind the scenes is more like how you and Bryan wrote it, with var i; at the very top.
It's certainly better to write the code the way you did in your answer and not how I have in my previous comment but they would both work the same way.
Steven Parker
243,658 PointsAfter looking it up I see that "JavaScript only hoists declarations, not initializations." I wasn't previously aware of that, partly because I very rarely declare without initializing, and as matter of practice never assign before declaring.
I love how contributing to the forum leads to learning things I might never know otherwise.
Jason Anello
Courses Plus Student 94,610 PointsYes, I've certainly learned a lot from your answers as well as others.
I'd say this variable hoisting is probably one of the quirks of javascript that can lead to a lot of confusion with beginners.
I think it's a good thing that we'll be moving on to using let and const and at least in this respect it will work more like what we're used to with C-like languages.
Shawn Denham
Python Development Techdegree Student 17,802 PointsHey Brian I know you said you solved your own question but you did not say how. Here is what I came up with. I found 2 main issues. One was variable scope and the other was initializing lightLevel and itemLight with a value of 0.0.
var itemList = ["prim", "spec", "heavy", "ghost", "helm", "chest", "legs", "class item", "artifact"];
var lightLevel = 0.0;
var itemLight= 0.0;
for (i = 0; i < itemList.length; i++) {
itemLight = prompt("Enter Light level for " + itemList[i] + ": ");
lightLevel += parseFloat(itemLight);
}
var averageLight = lightLevel / 9.0;
alert("Light level is currently: " + averageLight);
Henrik Christensen
Python Web Development Techdegree Student 38,322 PointsI'm not sure if loops can have "local" variables like functions but if they can then your problem might be that "lightLevel" is a local variable hidden inside the loop - but I'm not sure if I'm correct because I'm still very new to JS....
anyway, I hope this could help you in any way :)
Bryan Valencia
Full Stack JavaScript Techdegree Student 4,733 PointsBryan Valencia
Full Stack JavaScript Techdegree Student 4,733 PointsSolved my own question