JavaScript Patterns : Minimizing Globals

9/23/2010 11:41:43 AM
JavaScript uses functions to manage scope. A variable declared inside of a function is local to that function and not available outside the function. On the other hand,global variables are those declared outside of any function or simply used without being declared.

Every JavaScript environment has a global object accessible when you use this outside of any function. Every global variable you create becomes a property of the global object. In browsers, for convenience, there is an additional property of the global object called window that (usually) points to the global object itself. The following code snippet shows how to create and access a global variable in a browser environment:

myglobal = "hello"; // antipattern
console.log(myglobal); // "hello"
console.log(window.myglobal); // "hello"
console.log(window["myglobal"]); // "hello"
console.log(this.myglobal); // "hello"

1. The Problem with Globals

The problem with global variables is that they are shared among all the code in your JavaScript application or web page. They live in the same global namespace and there is always a chance of naming collisions—when two separate parts of an application define global variables with the same name but with different purposes.

It’s also common for web pages to include code not written by the developers of the page, for example:

  • A third-party JavaScript library

  • Scripts from an advertising partner

  • Code from a third-party user tracking and analytics script

  • Different kinds of widgets, badges, and buttons

Let’s say that one of the third-party scripts defines a global variable, called, for example, result. Then later in one of your functions you define another global variable called result. The outcome of that is the last result variable overwrites the previous ones, and the third-party script may just stop working.

Therefore it’s important to be a good neighbor to the other scripts that may be in the same page and use as few global variables as possible. Later in the book you learn about strategies to minimize the number of globals, such as the namespacing pattern or the self-executing immediate functions, but the most important pattern for having fewer globals is to always use var to declare variables.

It is surprisingly easy to create globals involuntarily because of two JavaScript features. First, you can use variables without even declaring them. And second, JavaScript has the notion of implied globals, meaning that any variable you don’t declare becomes a property of the global object (and is accessible just like a properly declared global variable). Consider the following example:

function sum(x, y) {
// antipattern: implied global
result = x + y;
return result;

In this code, result is used without being declared. The code works fine, but after calling the function you end up with one more variable result in the global namespace that can be a source of problems.

The rule of thumb is to always declare variables with var, as demonstrated in the improved version of the sum() function:

function sum(x, y) {
var result = x + y;
return result;

Another antipattern that creates implied globals is to chain assignments as part of a var declaration. In the following snippet, a is local but b becomes global, which is probably not what you meant to do:

// antipattern, do not use
function foo() {
var a = b = 0;

// ...

If you’re wondering why that happens, it’s because of the right-to-left evaluation. First, the expression b = 0 is evaluated and in this case b is not declared. The return value of this expression is 0, and it’s assigned to the new local variable declared with var a. In other words, it’s as if you’ve typed:

var a = (b = 0);

If you’ve already declared the variables, chaining assignments is fine and doesn’t create unexpected globals. Example:

function foo() {
var a, b;
// ...
a = b = 0; // both local

Note: Yet another reason to avoid globals is portability. If you want your code to run in different environments (hosts), it’s dangerous to use globals because you can accidentally overwrite a host object that doesn’t exist in your original environment (so you thought the name was safe to use) but which does in some of the others.

2. Side Effects When Forgetting var

There’s one slight difference between implied globals and explicitly defined ones—the difference is in the ability to undefine these variables using the delete operator:

  • Globals created with var (those created in the program outside of any function) cannot be deleted.

  • Implied globals created without var (regardless if created inside functions) can be deleted.

This shows that implied globals are technically not real variables, but they are properties of the global object. Properties can be deleted with the delete operator whereas variables cannot:

// define three globals
var global_var = 1;
global_novar = 2; // antipattern
(function () {
global_fromfunc = 3; // antipattern

// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true

// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

In ES5 strict mode, assignments to undeclared variables (such as the two antipatterns in the preceding snippet) will throw an error.

3. Access to the Global Object

In the browsers, the global object is accessible from any part of the code via the window property (unless you’ve done something special and unexpected such as declaring a local variable named window). But in other environments this convenience property may be called something else (or even not available to the programmer). If you need to access the global object without hard-coding the identifier window, you can do the following from any level of nested function scope:

var global = (function () {
return this;

This way you can always get the global object, because inside functions that were invoked as functions (that is, not as constrictors with new) this should always point to the global object. This is actually no longer the case in ECMAScript 5 in strict mode, so you have to adopt a different pattern when your code is in strict mode. For example, if you’re developing a library, you can wrap your library code in an immediate function and then from the global scope, pass a reference to this as a parameter to your immediate function.

4. Single var Pattern

Using a single var statement at the top of your functions is a useful pattern to adopt. It has the following benefits:

  • Provides a single place to look for all the local variables needed by the function

  • Prevents logical errors when a variable is used before it’s defined (see Section 2.2.5)

  • Helps you remember to declare variables and therefore minimize globals

  • Is less code (to type and to transfer over the wire)

The single var pattern looks like this:

function func() {
var a = 1,
b = 2,
sum = a + b,
myobject = {},

// function body...


You use one var statement and declare multiple variables delimited by commas. It’s a good practice to also initialize the variable with an initial value at the time you declare it. This can prevent logical errors (all uninitialized and declared variables are initialized with the value undefined) and also improve the code readability. When you look at the code later, you can get an idea about the intended use of a variable based on its initial value—for example, was it supposed to be an object or an integer?

You can also do some actual work at the time of the declaration, like the case with sum = a + b in the preceding code. Another example is when working with DOM (Document Object Model) references. You can assign DOM references to local variables together with the single declaration, as the following code demonstrates:

function updateElement() {
var el = document.getElementById("result"),
style =;

// do something with el and style...


5. Hoisting: A Problem with Scattered vars

JavaScript enables you to have multiple var statements anywhere in a function, and they all act as if the variables were declared at the top of the function. This behavior is known as hoisting. This can lead to logical errors when you use a variable and then you declare it further in the function. For JavaScript, as long as a variable is in the same scope (same function), it’s considered declared, even when it’s used before the var declaration. Take a look at this example:

// antipattern
myname = "global"; // global variable
function func() {
alert(myname); // "undefined"
var myname = "local";
alert(myname); // "local"

In this example, you might expect that the first alert() will prompt “global” and the second will prompt “local.” It’s a reasonable expectation because, at the time of the first alert, myname was not declared and therefore the function should probably “see” the global myname. But that’s not how it works. The first alert will say “undefined” because myname is considered declared as a local variable to the function. (Although the declaration comes after.) All the variable declarations get hoisted to the top of the function. Therefore to avoid this type of confusion, it’s best to declare upfront all variables you intend to use.

The preceding code snippet will behave as if it were implemented like so:

myname = "global"; // global variable
function func() {
var myname; // same as -> var myname = undefined;
alert(myname); // "undefined"
myname = "local";
alert(myname); // "local"

Note: For completeness, let’s mention that actually at the implementation level things are a little more complex. There are two stages of the code handling, where variables, function declarations, and formal parameters are created at the first stage, which is the stage of parsing and entering the context. In the second stage, the stage of runtime code execution, function expressions and unqualified identifiers (undeclared variables) are created. But for practical purposes, we can adopt the concept of hoisting, which is actually not defined by ECMAScript standard but is commonly used to describe the behavior.
Most View
Windows Server 2012 : Implementing Group Policy preferences (part 2) - Understanding preferences - Common options, Using environment variables
The Volkswagen Polo 1.5 TDI – Offer Effortless Performance In All Situations (Part 1)
Acoustic Energy AE 305 Stand Mounting Speaker
Nokia Lumia 920 - Windows Phone 8 And Magic Camera (Part 3)
Use Aperture’s Tools To Rescue Flat Images
Group Test: Laptops Running Windows 8 (Part 1) - Asus Zenbook UX32A, HP Envy 4-1020ea, lenovo IdeaPad U410
Protecting SQL Server Data : TRANSPARENT DATA ENCRYPTION (part 4) - Verifying TDE - Using Dm_Database_Encryption_Keys
Downloading and Installing Nginx HTTP Server : Configure options
Suryl Guardian - Protect Your PC From Malware And Other Problems
Back To School - The iOS Study Companion (Part 2)
- First look: Apple Watch

- 10 Amazing Tools You Should Be Using with Dropbox
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Biztalk Exchange Server Microsoft LynC Server Microsoft Dynamic Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Indesign Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe After Effects Adobe Photoshop Adobe Fireworks Adobe Flash Catalyst Corel Painter X CorelDRAW X5 CorelDraw 10 QuarkXPress 8 windows Phone 7 windows Phone 8 BlackBerry Android Ipad Iphone iOS
Top 10
OPEL MERIVA : Making a grand entrance
FORD MONDEO 2.0 ECOBOOST : Modern Mondeo
BMW 650i COUPE : Sexy retooling of BMW's 6-series
BMW 120d; M135i - Finely tuned
PHP Tutorials : Storing Images in MySQL with PHP (part 2) - Creating the HTML, Inserting the Image into MySQL
PHP Tutorials : Storing Images in MySQL with PHP (part 1) - Why store binary files in MySQL using PHP?
Java Tutorials : Nested For Loop (part 2) - Program to create a Two-Dimensional Array
Java Tutorials : Nested For Loop (part 1)
C# Tutorial: Reading and Writing XML Files (part 2) - Reading XML Files
C# Tutorial: Reading and Writing XML Files (part 1) - Writing XML Files