JavaScript Variables and Functions are Hoisted Prior to Execution

To the uninitiated, the JavaScript programming language has many peculiarities. One such oddity of the language is a concept referred to as hoisting. Consider the following code snippet:

console.log(episodeSevenTitle);

var episodeSevenTitle = 'The Force Awakens';

console.log(episodeSevenTitle);

The variable episodeSevenTitle is referenced in the first line of code although it isn't declared until the next line. This example would result in a compilation or runtime error in most programming languages due to the fact that a variable is referenced prior to its declaration. Not so with JavaScript. Here is the output from the code snippet:

undefined
The Force Awakens

As you can see, undefined is output followed by the string "The Force Awakens". At first glance, one might presume that undefined refers to the fact that the code attempts to output the value of episodeSevenTitle prior to it existing. However, if episodeSevenTitle doesn't exist at that point in the code, the JavaScript interpreter would throw an error. Take a look at the following example without a variable declaration:

console.log(episodeEightTitle);

Here is the output:

console.log(episodeEightTitle);
            ^
ReferenceError: episodeEightTitle is not defined

As you can see, the JavaScript interpreter complains that episodeEightTitle does not exist.
So how is it that in the first example the JavaScript interpreter is able to successfully attempt to output the value of a variable prior to its declaration? The answer is because episodeSevenTitle exists prior to the execution of the first line of code.

The Execution Context

All JavaScript code executes in what is called an execution context. The execution context is comprised of two phases: the creation phase and the execution phase.

During the first phase — the creation phase — the JavaScript interpreter places variables and functions into memory space. (Also, the scope chain is created and the value of this is set during this phase, but I'll save that for another post.)

Although the interpreter creates memory for variables, it does not execute assignment statements during the creation phase. Instead, variables are initially set to a value called undefined (see Bonus Tip below).

The second phase, referred to as the execution phase, is when the interpreter begins to execute lines of code. At this stage, the code can reference variables and functions that were placed in memory space during the creation phase.

Creating memory space for variables and functions in the creation phase and making them available during the execution phase even when they are referenced prior to their declaration is known as hoisting.

Revisiting the Hoisting Example

Now that we understand that JavaScript code is executed in an execution context, and that execution contexts have two phases, let's revisit the first example:

console.log(episodeSevenTitle);

var episodeSevenTitle = 'The Force Awakens';

console.log(episodeSevenTitle);

During the creation phase of the execution context, memory is allocated for the variable episodeSevenTitle, and it is set to undefined. So when the execution phase begins, episodeSevenTitle already exists, yielding the following output:

undefined
The Force Awakens

undefined is output first because that is the initial value of episodeSevenTitle after the creation phase. episodeSevenTitle is then set to "The Force Awakens", which is the value that is output in the last line of code.

Hoisting also applies to functions, allowing a function to be called prior to it's definition:

sayGoodbye();

function sayGoodbye() {
  console.log('May the force be with you.');
}

Output:

May the force be with you.

Bonus Tip

In JavaScript, the term undefined is a bit of a misnomer.

Do not confuse undefined with the "not defined" error message. "Not defined" means that code references a variable or function that has not been declared. undefined, on the other hand, is an actual value that can be assigned to a variable:

var jedi = undefined; // Never do this.

undefined is used by the JavaScript interpreter to indicate that a variable has been declared, but has not been set to a value:

var jedi;
console.log(jedi);

Output:

undefined

Additional Reading

Read more about JavaScript's undefined value here.