⚠️ Warning: this is an old article and may include information that’s out of date. ⚠️
Introduction
One of the things that’s always been confusing to me is that there are multiple ways to declare variables in JavaScript, and some ways are better than others. For the beginner programmer, just getting to code to work means complete success, but for the intermediate or advanced programmer, this is just the first step. The next step is to clean up the code and make sure everything is written in the best way it could have been written.
Declaring variables seems like such a basic thing that one almost feels insulted reading about it. Yes, this whole post is about declaring variables. But not just this – it’s about declaring variables the right way. This means declaring variables in the scope they were intended to be declared in. For the most part this means writing variables in the scope of a function, as opposed to the global namespace (in which everything becomes a property of the window object).
Global variables can be declared in functions
When I was starting to learn JavaScript, I read about global and functional scope and wrongly assumed that functions completely protected the variables declared inside. As it turns out, there’s many ways to create global variables in JavaScript, and none of them throw up red flags or sound off bells and whistles (unfortunately).
Here’s a few ways to create global variables in JavaScript:
// Creating global variables outside of a function window.global1 = 1; global2 = 2; var global3 = 3; // Created global variables within a function function test() { global4 = 4; window.global5 = 5; }; test();
You can confirm this for yourself by checking the values of the variables with alert().
Good practice: always precede variables with var
What I learned was that it was essentially good practice to always write variables preceded by the var keyword. For variables declared outside of functions this has no effect – they are still global, but for variables within functions this ensures that they’re kept within their functional scope:
var global = null; function test() { var local = null; } test();
Same name, but different variables
And check this out – confusingly, you can create a global variable, then create a variable with the same name that’s functionally-scoped, yet a completely different variable!
var number = 0; function test() { var number = 1; } test(); alert(number); // 0
When you precede a variable with the var keyword, you’re essentially saying you’re creating the variable for the first time. So when you create “number” inside the function, no error is thrown because the variable is created in the function’s scope. If you try to create another variable with the name “number” inside the function, you will get an error because it’s already been defined within the scope.
There’s no such thing as magical protective parenthesis
For some reason I was further mistaken into believing that extra parenthesis around an anonymous function magically protected all the variables within:
(function() { global = null; var local = null; })();
Nope – as you can see, the global variable is still global since it’s not preceded by the var keyword. However, the local variable is local because it’s within its functional scope and preceded by the var keyword.
Shorthand for declaring multiple functionally-scoped variables
The following code ensures each variable is functionally (locally) scoped, even though only the first variable is preceded by the var keyword:
// shorthand #1 function test() { var local1 = null, local2 = null; } test(); // shorthand #2 function test2() { var local1, local2; // these are of type 'undefined' but they have functional scope! } test2();
Multiple variable declaration equivalence gives different scope to each variable
Today I learned another way to mistakenly create a global variable. Trying to be fancy and declare multiple variables to be the same value, I mistakenly created a global variable (again, no bells and whistles went off to warn me, unfortunately):
function test() { var local = global = null; } test();
This sets both variables to “null” using the shortest code possible, but unfortunately only the variable “local” is preceded by the var keyword, so only that variable will be in its proper functional scope. Variable “global”, on the other hand, is… well… global. (thanks to Crescent Fish)
You learn something new every day…
Update 1
If you want to check your code for “accidental global variables” you can use JSLint or you can even use Firebug (click on the Script tab, then click on “New watch expression…”, then type “window”, which will display all the properties of the window object – these are all global variables!). Thanks to Nick for the Firebug tip.
Update 2
Just another quick note to remind you that after a variable has been initially declared, the scope will not change. Which is why you can redefine variables, but have them keep their scope:
function test() { var local = null; local = 5; // still keeps its local/functional scope } test();
As you can see above, the variable “local” keeps its local scope, even though it’s redefined to be 5. This is one of the reasons it’s recommended to declare all variables at the start of a function – to make sure the scope gets set correctly.
One final note: var should only be used when declaring a variable for the first time. If you try to use var for the same variable name in the same scope, it will result in an error:
function test() { var local = null; var local = 5; // throws an error! } test();
Comments