pierrespring.com

geek, punk, pussy …

My variable declaration got hoisted

I already talked about function scope in my last blogpost. Yet to fully understand how functions scope works, it might be good to look at the hoisting of variable declarations.

To non-native english speakers like me, the word hoisting itself presents a certain mystery. Here is what Wiktionary tells us:

Verb to hoist: To raise; to lift; to elevate; especially, to raise or lift to a desired elevation, by means of tackle or pulley, as a sail, a flag, a heavy package or weight.

This is precisely what JavaScript does with a variable declaration.

The var statement

var counter = 0;

gets split into two statements:

// A var statement in which the variable counter is declared and
// initialized to undefined.
var counter;

// An assignment statement which assigns the value 0 to the variable.
counter = 0;

When we say that the variable declaration gets hoisted, we mean that the declaration part of the var counter = 0; statement is put to the beginning of the function by the interpreter, meaning that the two following functions are equal:

var f1 = function () {
   // some code
   var counter = 0;
   // some more code
}

var f2 = function () {
   var counter; // initialized with undefined
   // some code
   counter = 0;
   // some more code
}

f1 gets actually transformed into f2.

Remember how we defined function scope: A variable declared anywhere in the function is visible everywhere in the function. The hoisting of variable declarations is the reason for this.

Hoisting of the variable declarations is also the reason we recommended to declare variables in the beginning of the function in JavaScript. This is different from most C like languages, in which it is recommended to declare variables where they are actually used.

Let’s look at an example to see why declaring the variables at the top of a function is important for a better understanding of the program:

// a global variable
var counter = 0;

var f = function (data) {
   counter++;
   // so something
   for (var counter = 0; counter < data.length; counter++) {
       // do something
   }
}
f([1,2,3]);
alert(counter); // -> 0

This seems wired, right. The increment of counter++ at the beginning of f() seems to be applied on the global counter variable. But due to the hoisting of the declaration within the for(;;) loop, the increment is applied to the counter declared in the loop.

That’s it. I think that I coverd all the basics of function scope and lexical scoping in the last two posts. In my next post, I’ll show how to rewrite f in order to be able to use a counter variable within the loop and still have access to the counter from the enclosing scope.

One Response to “My variable declaration got hoisted”

  1. [...] JavaScript. Read about JavaScript Variable Hoisting at JavaScript Scoping and Hoisting and My variable declaration got hoisted. For more information on closures, refer to Closures in JavaScript by James Padolsey and [...]