A Consideration of Variable and Function Scope in JavaScript

Many aspects of JavaScript code development are taken for granted, and scope is really no different. Of course, in many cases where minimal code is required, variable scope (or function scope) is a non-issue. But if you’re planning to get into larger application development with JavaScript, then you need to understand at least the basics on scope in JavaScript.

Using some simple code examples, I’m going to run through the basics of scope and try to give beginning to intermediate JavaScript developers a better grasp of this very important concept.

Execution Context

JavaScript programs have what is referred to as the execution context of a variable or function, which defines exactly what data the function or variable has access to. Here is a simple example to illustrate two different contexts in one JavaScript program:

In the above code, we’re declaring two variables, sport and player. Both variables are accessible inside the getPlayer function, since they reside in the global context. Therefore, based on the sport variable’s value, we can determine a new value for the player variable.

But, since the function is, in itself, a different context, the variable player2 is only accessible inside the function, and not in the global context. So, this script runs fine up until the last line, which produces an error because the global context does not recognize the existence of player2.

What Exactly is the Global Context?

The global context of every JavaScript program coded for the browser is the window. This can be demonstrated with some changes to the code we just wrote. We’ll omit the last line, and instead execute the getPlayer function as a method on the window object. We’ll also “return” the value of player and wrap an alert around the function call, to see the return value. After that, we’ll alert the player variable as a property of the window object. Here is the code:

So if we omit the reference to the window object, the code will run exactly the same way, because all code that is not inside a function is in the global context, therefore belonging to the window object. Here’s a demo page:

Nested Functions Have Their Own Context

As you’ve probably figured out, we could nest functions inside of our getPlayer function, and each of those nested functions would behave under the same principles we’ve already discussed. Let’s modify our code to demonstrate this:

It’s a little complex at first, but the above code is a good demonstration of how nested functions affect scope. First, as done previously, we declare the sport and player variables. Inside the getPlayer function we decide the value of player. Then we have the new getPlayer2 function, nested inside getPlayer. This nested function determines the value of player2 based on the value of player. Finally, the value of player2 is returned. So, when getPlayer is called in the alert, we can see the current value of player2.

But this code produces an error when it gets to the last line. The last line tries to execute the getPlayer2 function in the global context, but this doesn’t work because the getPlayer2 function is not in the global context. Let’s try to alert the getPlayer2 function right before the return statement in the getPlayer function:

The above code will alert the value of player2 twice, then produce the same error as in the previous code. The first alert works because the getPlayer2 function is available inside the getPlayer function context, but not in the global context.

Details to Take Note of in our Example

Here are some simple facts specifically associated with the above example code, to help you understand what is and isn’t accessible in the 3 different contexts:

The player variable is accessible in all 3 contexts (the global, plus both functions), because it is declared in the global context

The getPlayer2 function is not accessible in the global context because it is declared inside the getPlayer function

The getPlayer2 function is accessible inside the getPlayer function

The player2 variable is only accessible inside the getPlayer2 function, therefore is not available in the global context or in the getPlayer function

Summary

To summarize, every JavaScript program has at least one execution context (the window object), and every function inside that context will add yet another, separate, execution context. Also, all nested contexts will have access to their container contexts, which is somewhat similar to how the CSS Cascade works — although that’s kind of like comparing apples to oranges. Finally, the global context only has access to variables and functions declared inside the global context. And the same would be true for other “parent” contexts that have “child” contexts — they only have access to variables and functions in their own context and above.

I think variable and function scope in JavaScript is fairly intuitive and easy to grasp once you get your hands dirty and immerse yourself in it. There’s much more I could discuss on this topic, but I think that’s enough for the purposes of this post. Feel free to offer comments on anything you feel is important to consider with regards to scope in JavaScript.

“Evan Longoria” is an American male baseball player. “Eva Longoria” (notice the N missing), is a female actress. They are two different people. I guess the subtle difference tends to look like an error to those not familiar with U.S. pop culture! :o)

Leave a Reply

Comment Rules: Please use a real name or alias. Keywords are not allowed in the "name" field. If you use keywords, your comment will be deleted, or your name will be replaced with the alias from your email address. No foul language, please. Thank you for cooperating.

Instructions for code snippets: Wrap inline code in <code> tags; wrap blocks of code in <pre> and <code> tags. When you want your HTML to display on the page in a code snippet inside of <code> tags, make sure you use &lt; and &gt; instead of < and >, otherwise your code will be eaten by pink unicorns.