Lesson Tuesday

In this lesson, we'll discuss variable scope, one of the most important concepts in computer programming. The scope of a variable determines where it will be available in our application and whether we can access or modify it. Make sure you take the time to understand this essential concept. Problems with scope can lead to a lot of bugs as well as code that simply doesn't the work. You will get plenty of chances to deal with these bugs and learn firsthand about scope.

There are two types of scope: global and local.

Global scope

Variables declared outside of functions have global scope which means that all code and functions can access them. They are at the "top level" of a program.

Let's look at an example:

let 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.

As we'll see, we are able to modify globalString everywhere we try. The alert will be updated inside the function and we'll be able to read and the new value outside of the function.

In general, global scope should be avoided. Unless the lessons state otherwise, there is no need to use global variables in either the daily classwork or independent projects.

Local scope

Variables declared inside of functions have local scope. This 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 its scope ends when the function is finished processing. In fact, the variable is created and destroyed each time the function runs.

Let's move our variable inside our sampleFunction(). We'll also change the name to localString to reflect the fact that the variable is now local. Let's see what happens:


function sampleFunction() {
  let localString = "This is a local variable";
  alert(localString);
  localString = "This is a local variable update!!";
  alert(localString);
}

sampleFunction();
alert(localString);

If we run this code, the first two alerts inside the function will run as expected when the function is called.

However, the third alert, which is outside of the function, will not run. Instead, we'll get the following error:

Uncaught ReferenceError: localString is not defined

Let's look at another example:

variable-scope-example.html
<!DOCTYPE html>
<html lang="en-US">
<head>
  <script src="js/jquery-3.5.1.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) {
    const 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 are Bad

Let's take one more look at our local variable example. We will make one small change:


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

sampleFunction();
alert(localString);

In this example, all we did is remove the let before localString.

What happens when we run the code? Try it out in the console.

Everything runs correctly, including the alert outside of the function. However, this is not what we want to happen. The variable has been declared inside the function, so shouldn't it be scoped there, too?

This is a bad thing that JavaScript does that's a holdover from the early days of JavaScript. If a variable is declared without let, const, or var, it's automatically global no matter where it is defined.

You will run into errors and bad bugs if you let variables run amok like this, so it's important to always declare a variable with let or const.

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. For instance, let's say you were working with a huge codebase that had a function like this:

function(event) {
  alert(whatToSay);
}

It might 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.

Let's take a look at an analogy to solidify the concept. Let's say we have a fun but overly feisty golden retriever named Max. Max isn't allowed into most rooms of the house because he will chew everything up and make a mess. However, it's okay if he hangs out in the den because the den has been Max-proofed. If we wanted to ensure this in our code, we need to scope Max to just the den like this:

function den() {
  let dog = "Max";
}

function livingRoom() {
}

function kitchen() {
}

In the code above, Max is locally scoped to the den. He can't be called or redefined in the livingRoom() or kitchen() function.

However, he will certainly run amok if we do this:

let dog = "Max";

function den() {
}

function livingRoom() {
}

function kitchen() {
}

Now he is global in scope and he has access to all the rooms. He could chew up a couch in the livingRoom() function and eat all the food lying out in the kitchen() function. As you can imagine, this is not at all good! Even if you don't yet see how global variables can cause harm to our code (because our code samples are small), just trust the analogy above. Global variables can truly wreck havoc.

For that reason, avoid using global variables, including in your independent projects. There will be rare occasions when we will use global variables in lessons (or when you might see reason to use them in your own code). Global variables exist for a reason - and they can be needed sometimes. However, they are too often used as a crutch for people new to coding. In the coming weeks, if the lessons don't specify using a global variable, you almost certainly don't need one. So stick with using locally scoped variables!

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.

Lesson 40 of 61
Last updated July 30, 2020