Advanced level for developers only.

JavascriptToday I’ll talk about variables Declaration in Javascript, I’ll start with their scope and I’ll continue with the hoisting, it’s a strange aspect of the language – to say the least – at first.

Variables Declaration

Variables are defined by a name and a value, the name must start with a letter or an underscore. Letters, numbers and $, _ and & are allowed to compose the rest of the name. Be careful to the case:

MyVar !== myvar

Keep in mind these reserved keyword, do not use them as variable’s names, here is a complete list:

break continue do for import
new this void case default
else function in return typeof
while comment delete export if
label switch var with abstract
implements protected boolean instanceOf public
byte int short char interface
static double long synchronized false
native throws final null transient
float package true goto private
catch enum throw class extends
try const finally debugger super
alert eval Link outerHeight scrollTo
Anchor FileUpload location outerWidth Select
Area find Location Packages self
arguments focus locationbar pageXoffset setInterval
Array Form Math pageYoffset setTimeout
assign Frame menubar parent status
blur frames MimeType parseFloat statusbar
Boolean Function moveBy parseInt stop
Button getClass moveTo Password String
callee Hidden name personalbar Submit
caller history NaN Plugin sun
captureEvents History navigate print taint
Checkbox home navigator prompt Text
clearInterval Image Navigator prototype Textarea
clearTimeout Infinity netscape Radio toolbar
close innerHeight Number ref top
closed innerWidth Object RegExp toString
confirm isFinite onBlur releaseEvents unescape
constructor isNan onError Reset untaint
Date java onFocus resizeBy unwatch
defaultStatus JavaArray onLoad resizeTo valueOf
document JavaClass onUnload routeEvent watch
Document JavaObject open scroll window
Element JavaPackage opener scrollbars Window
escape length Option scrollBy

Important: Always declare your non global variables (see the hoisting section below) with the “var” keyword explicitly.
Next to that, there are three methods to declare global variables, here they are:

1
2
3
4
5
6
window.myVar = "myValue";
// Same as
var myVar = "myValue";

// Don't do this
myVar = "myValue";

Variables Scope

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Global var, part of the window object
var myVar1 = "Variable 1";

function myFunction1 () {
// Local variable, contained in the function's scope
var myVar2 = "Variable 2";
// Global variable (bad declaration), also part of the window object
myVar3 = "Variable 3";

alert(myVar1); // Display "Variable 1"
alert(myVar2); // Display "Variable 2"
alert(myVar3); // Display "Variable 3"
myVar1 = Display "I change of value !!!";
}
myFunction1();
alert(myVar1); // Display "I change of value !!!"
alert(myVar3); // Display "Variable 3"
//alert(myVar2); // If not commented, would throw an error "myVar2 is not defined", because myVar2 is out of its scope here.

function myFunction2 () {
// Local variable with a similar name as a global one
var myVar1 = "Local Variable 1";
alert(myVar1); // Display the local variable: "Local Variable 1"
}
myFunction2();
// The value of the global variable of the same name in unchanged.
alert(myVar1); // Display "I change of value !!!"

As you have noticed I’m a big fan of the alert function. 🙂

The important point here
Global variables are accessible from the whole script, in any functions (even nested ones), objects… If a local variable has the same name as a global one, this last one would be ignored in the local scope. Always declare your variables with the “var” keyword in order to avoid confusion. It’s the kind of mistake that can be hard to spot.

Here is a little optimization for your script performance, stock in local variables the global (or superior) ones you use inside your functions, mainly if they are nested.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
window.myVar1 = "value 1";

// Bad
function myGlobalFunction1 () {
// We declare a nested function
function myLocalFunction1 () {
alert(myVar1);
// Search in the function scope then goes one level above "myGlobalFunction1" then in the global one to finally find the value on the variable.
}
myLocalFunction1();
}
myGlobalFunction1();

function myGlobalFunction2 () {
function myLocalFunction2 () {
var v1 = window.myVar1;
alert(v1);
// Alert "value 1" without checking out of the local scope
}
myLocalFunction2();
}
myGlobalFunction2();

In the second level nested function (myLocalFunction2), any change on the local variable won’t affect the global one.
For example v1 = “New value”; won’t change window.maVar1 unless you add window.maVar1 = v1; in your code.

The hoisting

Let’s start the fun now and a demonstration is better than long speeches, let’s take the following code:

1
2
3
4
5
6
7
8
9
var myVar = "Global Variable";
var myFunction = function () {
if (!myVar) {
var myVar = "Local Variable";
}
alert(myVar);
return;
};
myFunction();

What do you think the following script will “alert”?

The answer is Local Variable, this what is called the hoisting and I’ll try to explain it.
In Javascript, any declared variable – even in a non interpreted part of the code: conditional blocks like above, after the return instruction… – will be hoisted at the top of the function. The code above is actually interpreted this way:

1
2
3
4
5
6
7
8
9
10
var myVar = "Global Variable";
var myFunction = function () {
var myVar; // hoisted variable with undefined value
if (!myVar) {
myVar = "Local Variable";
}
alert(myVar);
return;
};
myFunction();

This is the reason why JS Gurus, like Douglas Crockford in his good parts, advise to declare all the variables of a function at its top, this looks like that:

1
2
3
4
5
6
7
8
9
10
11
12
var myFunction = function () {
var myVar1, myVar2, myVar3...;
//Your rocking code...
};

// This is equivalent to:
var myFunction = function () {
var myVar1;
var myVar2;
var myVar3;
//Your rocking code...
};

But that’s not all, there is another specificity to make things even more fun, yes believe me… 🙂
Functions can be declared in two different ways that will impact their behavior during the execution of the script.

Function Expression

1
2
3
4
5
//alert(myFunction());
alert(myFunction);
var myFunction = function () {
return "myValue";
};

The commented line would trigger an error, myFunction is not a function, the second would display “undefined”;

Function Declaration

1
2
3
4
alert(myFunction());
function myFunction () {
return "myValue";
}

Displays “myValue” because the function is declared before the execution of the code.

The declared function is hoisted at the top of the scope with its value, the expressed function acts more like variables of other types and just its name is hoisted, not its body/value.

I hope I’ve been clear enough, do not hesitate to comment.