What is Variable Hoisting in JavaScript?

Consider the following code:

1
2
var sheldon = 'bazinga!';
alert(sheldon); // bazinga!

Okay, of course the alert will display “bazinga!.” That’s obvious; however, stick with me.

Let’s next create an immediate function, which alerts the same value.

1
2
3
4
5
var sheldon = 'bazinga!';
 
(function() {
  alert(sheldon); // bazinga!
})();

All right, all right. Still obvious, I know. Now, let’s throw a wrench into the mix, and create a local variable within this anonymous function of the same name.

1
2
3
4
5
6
  var sheldon = 'bazinga!';
 
(function() {
  alert(sheldon); // undefined
  var sheldon = 'local bazinga!';
})();

Huh? Why is the alert now displaying undefined? Even though we’ve declared a new variable, it’s still below the alert; so it shouldn’t have an effect, right? Wrong.

Variable Declarations are Hoisted

Within its current scope, regardless of where a variable is declared, it will be, behind the scenes, hoisted to the top. However, only the declaration will be hoisted. If the variable is also initialized, the current value, at the top of the scope, will initially be set to undefined.

Okay, let’s decipher the difference between the terms, declaration andinitialization. Assume the following line: var joe = 'plumber';

Declaration
1
var joe; // the declaration
Initialization
1
joe = 'plumber'; // the initialization

Now that we understand the terminology, we can more easily comprehend what’s happening under the hood. Consider the following bogus function.

1
2
3
4
5
6
7
8
(function() {
  var a = 'a';
  // lines of code
  var b = 'b';
  // more lines of code
  var c= 'c'; // antipattern
  // final lines of scripting
})();

Declare all variables at the top.

Note that what’s exemplified above is considered to be bad practice. Nonetheless, behind the scenes, all of those variable declarations — regardless of where they occur in the function scope — will be hoisted to the top, like so:

1
2
3
4
5
6
7
8
9
(function() {
  var a, b, c; // variables declared
  a = 'a';
  // lines of code
  b = 'b'; // initialized
  // more lines of code
  c= 'c'; // initialized
  // final lines of scripting
})();

Aha Moment

If we now return to the original confusing undefined piece of code, from above:

1
2
3
4
5
6
var sheldon = 'bazinga!';
 
(function() {
  alert(sheldon); // undefined
  var sheldon = 'local bazinga!';
})();

It should now make perfect sense why sheldon is alerting undefined. As we learned, as soon as the local variable, sheldon, was declared, it was automatically hoisted to the top of the function scope…above the alert. As a result, the variable had already been declared at the time of the alert; however, because initializations aren’t hoisted as well, the value of the variable is: undefined.

Summary

To put in simple words, function declarations and variable declarations are always moved (“hoisted”) invisibly to the top of their containing scope by the JavaScript interpreter. This means that code like this:


function foo() {
bar();
var x = 1;
}

is actually interpreted like this:

function foo() {
var x;
bar();
x = 1;
}

Advertisements

FancyUpload – AJAX Uploader with Progress Bar

FancyUpload is a file-input replacement which features an unobtrusive, multiple-file selection menu and queued upload with an animated progress bar.

It is easy to setup, is server independent, completely styleable via CSS and XHTML and uses MooTools to work in all modern browsers.

It is fully compatible with all A-Grade Browsers (Internet Explorer 6+, Opera 9, Firefox 1.5+ and Safari 2+)

Features

  • Select and upload multiple files
  • Filter files by type in the select dialog
  • Optional Events to add your own behaviour
  • Show and filter useful file information before the upload starts
  • Limit uploads by file count and/or file size
  • Platform and server independent, just needs Flash 8+ (> 95% penetration)
  • Unobtrusive, since the element is replaced after the swf loaded successfully
  • Cancel running uploads, add files during upload
  • Everything is optional, documented and easy editable

[ Demo ] [ Website ]