Variable Scope and Hoisting in JavaScript

What is Scope?

A variable’s scope determines which parts of the program can see and use it. JavaScript has global and local scopes. Any variable declared outside of any functions belongs to the global scope. It is accessible from anywhere in your code. Defining a function creates its own local scope, meaning the variable can only be accessed within that function. This is called function scoping.

This example demonstrates how the value of the variable test changes depending on its scope. During the function call, its value is “local”, but afterwards, execution returns to the global scope.

JS Bin on jsbin.com

If you are coming to JavaScript from another language that uses block scope (where every set of curly braces creates a new scope), you might expect JavaScript to do the same. However, in JavaScript, blocks like loops and conditionals do not create their own scope. A new scope is created only when you create a new function.

JavaScript is also lexically scoped. This means the program starts at the innermost scope and searches outwards until it finds the variable it needs. A child scope has access to parent’s variables, but not vice versa.

As shown by the console output in this example, inside the inner() function, the value of test is 2, not 1, because that is the first definition the code encounters when searching outwards.

JS Bin on jsbin.com

What is Hoisting?

Regardless of where a variable is declared within a given scope, all variable declarations are moved to the top of their scope. This is called hoisting. Note, hoisting only applies to declarations, not definitions. Declaration creates a variable, while definition assigns it an initial value. Take a look what happens when JavaScript encounters undeclared vs. undefined variables.

JS Bin on jsbin.com

Without an assigned value, the the value of veggie is undefined. cheese, however, is an undeclared variable, so the program crashes. Knowing that using an undeclared variable will crash the program, take a look at the next example.

JS Bin on jsbin.com

While fruit is not declared until the line after the first console.log, the function does not crash. This is because the declaration is hoisted to the top of the scope. undefined is logged because only the declaration is moved, not the definition. It is not until the second and third console.log statements that the value of fruit is defined.

Leave a Reply