A shiny silver telescope shown over a city

Variable scope can be one of the more confusing aspects of JavaScript: placing variables at the start of a script, where they seem to make the most sense, is strongly inadvisable, yet putting them in other places sometimes causes them not to work. So what’s the story?

The Dangers of Global Scope

It’s instinctive to write out your variables at the very start of a script. While that is a good idea in practice, let’s look at a very simple example to see how doing so can work against you:

<script>
	var testvar = "Greetings, citizen!";
</script>

Placed on a web page and viewed in a browser, we can use the console to view the variable. Typing testvar into the console gets you the anticipated:

> Greetings, citizen!

But typing window.testvar into the console will also provide the same result. This is an important clue: it means that testvar is attached to the window object, and is therefore available to every script on the page, a context known as root, base, or global scope. This sounds great, but carries a number of significant disadvantages:

  • Polluting global scope with variables makes it almost inevitable that there will be clashes and confusion between variable names as more scripts are added to the page.
  • Adding variables to global scope makes memory management harder, as global variables must always be maintained; local variables are only used and remembered in the context of their associated function.

Variables In Functions

JavaScript functions can reference variables “above” their scope, but the rest of the script can’t see variables inside the function. So in the following:

function showerbed() {
	var leeloo = "Multipass!";
}

The leeloo variable can only be referenced when script execution moves inside the showerbed() function, and can’t be referenced outside it. However, the function can still read any variables from its parent scope. That is, if we merge the two scripts above:

<script>
var testvar = "Greetings, citizen!";
function showerbed() { 
	var leeloo = "Multipass!";
	console.log(testvar +' '+leeloo);
}
showerbed();
</script>

We will see in the console:

 > Greetings, citizen! Multipass!

Scope could therefore be thought of as the answer to the question “what variables do I have access to at this point in the script?”

Tying Things Off

As your scripts become more complex, a combination of improvisation and force of habit tends to create name clashes: variables provided with the same identifier, in the same scope, that then conflict, potentially overwriting each other’s value. This can also happen with poorly planned scripts used on the same page:

<script>var protagonist = “Mr Shadow”;</script>
<script>var protagonist = “Corbin Dallas”;</script>

To avoid this, a well-designed script will take advantage of the fact that functions limit variables to function scope by employing them anonymously.

Photograph by MaO de Paris, under a Attribution-NonCommercial-NoDerivs 2.0 Generic Creative Commons license.

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.