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 Fixing Our Problem with Closures

Closures - function statements vs function expressions

When I enter this code:

var count     = 0
  , birdCount = countBirds()

var countBirds = function () { // function statement
  var count = 0

  var counter = function () {
    count += 1
    console.log(count + ' birds')
    return count + ' birds'
  } // counter inner fn

  return counter

} // countBirds outer fn


var countDogs = function () {
  count += 1
  return count + ' dogs'
}

birdCount()

I get the console error:

TypeError: countBirds is not a function
, birdCount = countBirds()

To fix the error, I use this code:

var count     = 0
  , birdCount = countBirds()

function countBirds () { // changed to function expression
  var count = 0

  var counter = function () {
    count += 1
    console.log(count + ' birds')
    return count + ' birds'
  } // counter inner fn

  return counter

} // countBirds outer fn


var countDogs = function () {
  count += 1
  return count + ' dogs'
}

birdCount()

Does anyone know why this is?

Thanks

1 Answer

Declarations are hoisted, initializations are not. Essentially, if you declare a variable with the var keyword, it is hoisted to global scope and assigned later. Lambda functions aren't declared at all and are therefore treated differently.

Basically, at runtime everything preceded by "var" becomes undefined and then JS fires the functions, in your case above, birdCount appears to be firing before countBirds is assigned, resulting in undefined.

I find it easier to declare the variables I intend to use at the highest scope at the top and assign them throughout the program.

var count     = 0
  , countBirds
  , birdCount;

countBirds = function () { // function statement
  var count = 0

  var counter = function () {
    count += 1
    console.log(count + ' birds')
    return count + ' birds'
  } // counter inner fn

  return counter

}; // countBirds outer fn

birdCount = countBirds();
birdCount();

More Reading

Hope this helps.

Excellent - thank you very much!