Variable Hoisting in JavaScript

If you are programming in JavaScript, the odds are that you come from C/C++/Java background and have been bitten by the web development bug. This might cause a couple of problems however, mostly because JavaScript is "Lisp in C's Clothing". So you might find yourself a little disoriented with the familiar syntax and sometimes very unintuitive execution. One thing that is not quite so easy to understand is the fact that functions are first class in JavaScript and that they do create closures. Couple that with lexical scoping and you can get some really unexpected results.

Connected to the concept of functions being first class is the notion of variable hoisting. Dictionary definition of "hoisting" is lifting or raising something up. And this exactly what JavaScript engines do. Any variable that is declared (be it initialized to a primitive data type, an object or even a method) anywhere in a function will actually be run as if they are declared in the beginning of that function. That is, they are raised to the top of the scope they are in. Initializations for that variable will not run however, since this is not what you normally expect, and because it would have caused rather unexpected run time peculiarities.

Consider the following JavaScript snippet:


function foo() {
// Some other stuff.
// blah blah blah

if (false) {
var myVar = "bar";
}

alert(myVar);
}
foo();

When you run above code, you will get an alert box with "undefined" in it. Even though what's inside the "if" conditional is not executed, the variable is nevertheless declared in the beginning of the function. So, in effect, the above code is equivalent to:

function foo() {
var myVar;
// Some other stuff.
// blah blah blah

if (false) {
myVar = "bar";
}

alert(myVar);
}
foo();

Note how the variable is taken and declared at the top while the initialization is left where it was.

But wait, there's more. Since the condition for the "if" is never true, execution does not enter inside the block, and thus it doesn't matter where it is placed in our function. Thus, below is equivalent to the two code fragments above:

function foo() {
// Some other stuff.
// blah blah blah

alert(myVar);

if (false) {
var myVar = "bar";
}
}
foo();


Contrast above executions with the below where you'll get a ReferenceError exception because myVar has not been declared.

function foo() {
// Some other stuff.
// blah blah blah
/
if (false) {
var myVar = "bar";
}
/
alert(myVar);
}

foo();

Variable hoisting is actually quite logical when you think about it, but you have to get into the mindset of functional programming. And because of such properties, variable hoisting is asked a lot on JavaScript quizzes found on the web.

I have to admit that the above example does not seem very likely in any code, but believe me you will one day come across it if you start coding complex JavaScript applications. When you do find yourself with bugs caused by hoisting, you might also understand the reason behind the coding convention where all variables are declared at the top of the scope, even if they are used at the very bottom. Don't be afraid though, JavaScript is still a beautiful language, if you try to understand it and use "the good parts".

Code corrupted. Insert fresh copy.

I recently started blogging again. One of the first things I did, I inserted some javascript code in the usual template that blogger provides. I saved the template and I got a bundle of errors. The first few errors were related to XML parsing, the new blogger engine couldn't parse my code. Apparently this is because of using "&" directly instead of "&", OK my fault. I fix these issues and then when I think that all should be well, I refresh my page to see

"Code corrupted. Insert fresh copy."
in the place where I inserted the code. After looking at the generated code, I see that my code is not in the place it should be, because the javascript code is actually inside html quotation characters (namely <!-- and -->) so the blogger engine didn't think it was any use and left them out of the generated code. I removed the quotes and voila, it works.

Hope this helps someone.

--

Bloggerda yeni sayılırım, bir javascript kodu eklemeye çalıştığımda çıkan hataları anlatacağım. İlk olarak, şablonu kaydet butonuna tıklayınca blogger amcam ben bunu parse edemiyorum sen bunu XML yap öyle gel dedi. Hemen "&" işaretlerini "&amp;" yaparak isteğini yerine getirdim. Daha sonra şablonu kaydettim. Sevinçle tarayıcımın "yenile" düğmesine basmıştım ki kodun olduğu bölümde
"Code corrupted. Insert fresh copy."
yazısını gördüm. Blogger amcamın oluşturduğu koda direk sayfadan bakınca eklediğim kodun yerinde yeller estiğini gördüm. Neymiş, blogger amcam javascript kodunun yorum kodları arasında (<!-- ve -->) olduğunu görünce gereksiz olduğunu sanarak oluşturduğu koda eklememiş. Kodu yorumlardan kurtarınca mutlu mesut hayatımıza devam edebiliriz.

Umarım birilerine yardımı dokunur.

--

tayfun