Variable Hoisting in Javascript
If you are coming from C# or Java background into C#, you might find scopes as very strange in java script. In this post, we will be trying to understand the scopes in C#. Specially, how javascript uses hoisting to for these out-of-ordinary scopes.
In other programming languages, we limit the scopes by introducing some explicit or implicit BEGIN and END markers (curly braces {} in C# / Java & indentation in Python). Since syntactically, javascript is Cish, it also has those curly braces. If you are coming from the background of C’ish languages, you might assume that they would limit the scope.
Let’s see the following code:
Here we have added a variable internaVar. We have tried limiting scope of the variable by keeping them inside the statement block. We are trying to access the block’s local variable outside the statement block. You might assume that this should fail at compile time. Well we don’t have that luxury in javascript. Actually the code still runs. If you add a breakpoint in chrome, you might see something like this:
The variable not only has it’s lifetime by maintaining the value assigned in the scope, it also has visibility outside the statement scope. So what is going on? Actually, this is a feature of java script called Variable hoisting, where it finds all declarations within a function and move them at them at the start of function. Since javascript has caused the declaration of internalVar in the function scope, it is available throughout the function, hence maintaining its lifetime and visibility.
How to avoid this?
In order to avoid this, we can use javascript lint library (jshint). Let’s move this code in a javascript (lintEx.js) file first, and remove all document.writeln methods. Linting allows us to identify the bad parts of javascript and gives suggestions to avoid the unexpected.
Now let’s install node module for jshint using node package manager (npm).
As we run the jshint tool for our javascript, it recognizes the issue and notifies us to fix the usage of a local variable out of our intended scope.
Best Practice
Since javascript doesn’t recognize a local scope, I think we should avoid declarations in a local scope. It’s like assembly where we have separate data segments. We can do all declarations in the beginning of the function and use the variables throughout the function. This is obviously different than our regular use of variables where we like to declare them in the least possible scope.