Lesson Tuesday

Variable Scope

Before we move on, let's pause to discuss variable scope. The scope of a variable defines where and when it is available to be used or modified. Scope can be global or local depending on how it is declared.

Global scope

Variables declared outside of functions have global scope which means that all code and functions can access them.

var globalString = "This is a global variable";

function sampleFunction() {
  alert(globalString);
  globalString = "This is a global variable update!!";
  alert(globalString);
}

alert(globalString);
sampleFunction();
alert(globalString);

Let's run this in JSFiddle and see what we get each time we ask for an alert.

Local scope

Variables declared inside of functions have local scope which means they are only locally available during the execution of the function. When we look at a variable that is defined within a function, we find that it's scope ends when the function is finished processing. In fact, the variable is created and destroyed each time the function runs.

If we move the variable declaration from the global to the local by adding it inside the function, let's see what happens:


function sampleFunction() {
  var globalString = "This is a global variable";
  alert(globalString);
  globalString = "This is a global variable update!!";
  alert(globalString);
}

alert(globalString);

Nothing. Look in the console and the error Uncaught ReferenceError: globalString is not defined. We have not run the function so as the error message indicates, globalString has not actually been defined yet. It now has local scope.

Let's look at another example:

variable-scope-example.html
<!DOCTYPE html>
<html>
  <head>
    <script src="js/jquery-1.10.2.js"></script>
    <script src="js/scripts.js"></script>
    <title>An adventure in variable scope</title>
  </head>
  <body>
    <div id="click-one">click me first</div>
    <div id="click-two">click me second</div>
  </body>
</html>
scripts.js
$(document).ready(function() {

  $("div#click-one").click(function(event) {
    var whatToSay = "Hello!";
    alert(whatToSay);
  });

  $("div#click-two").click(function(event) {
    alert(whatToSay);
  });
});

If we click click me first, a dialog box pops open that says "Hello!". If we then click click me second, what happens? Nothing. If we look to the JavaScript console, we find the familiar error Uncaught ReferenceError: whatToSay is not defined. And that's true. The whatToSay variable is defined inside a function. Therefore, the program only knows about the variable while it is inside the function processing the code there. As soon as the function is complete, the variable is no longer defined; it's outside the limits of whatToSay's variable scope.

Unscoped variables (bad practice!)

When you create a variable, it is important to declare it to the program using the var keyword.

If you declare a variable by assigning it a value like this (without var):

function Namer() {
  sampleName = "Cindy Lou"
}

JavaScript will make it a global variable automatically, even if it is inside of a function. In the above function, sampleName would become a global variable with global scope which allows any part of the code to access or modify it.

This is something you should never do. Always use the varkeyword to declare your variables and consciously determine whether their scope should be global or local.

Let's just carry this through so that you understand what's going on if you see it elsewhere:

scripts.js
$(document).ready(function() {

  $("div#click-one").click(function(event) {
    whatToSay = "Hello!";
    alert(whatToSay);
  });

  $("div#click-two").click(function(event) {
    alert(whatToSay);
  });
});

With the var keyword removed from whatToSay, if we click click me first and then click click me second, the dialog box will open up both times because it has defaulted to a global variable.

This code is very small, so you may not see the problem with using a global variable. But imagine a code base that's thousands or tens of thousands of lines long. If you see a function that looks like:

function(event) {
  alert(whatToSay);
}

it would be incredibly difficult to figure out where whatToSay was defined. And if whatToSay was used and changed in multiple places, it would be next to impossible to figure out where it's value was last set. (For a horror story on a missing var, read Geoffrey Hayes's "How one missing var ruined our launch" starting at the "Seem kinda bad?" paragraph.)

To conclude, always create variables with either global or local scope using the var keyword. Using scoped variables lets us easily follow the flow of our application and ensures our functions don't step on each other's execution in unexpected ways.

Terminology


  • Variables defined with var are scoped to the function in which they are defined. Omitting var automatically creates a global variable and is a bad practice.

  • Variable scope: A specific variable's "scope", which refers to where it's accessible and available for use.

  • Global scope: The variable scope of global variables which are declared outside of a function, allowing all functions the ability to access and use them.

  • Local scope: The variable scope of local variables which are declared within a function. Variables with local scope only exist and are available during the execution of the function in which they are defined.