var keyword, and by using the new
const keywords. Prior to ES6, using the
var keyword was the only way to declare a variable, but now we can use
const, which have stricter rules and make the code less error prone. We’ll explore the differences between all three keywords below.
In a script, the outermost scope is the global scope. Any variables declared in this scope become global variables and are accessible from anywhere in the program:
// Global Scope const name = "Monique"; function sayHi() console.log(`Hi $name`); sayHi(); // Hi Monique
As this simple example shows, the variable
name is global. It’s defined in the global scope, and is accessible throughout the program.
Any variables declared inside a block belong to that particular block and become local variables.
const. Any variable declared within that function is only accessible from that function and any nested functions.
A code block (
for, etc.) defines a scope only for variables declared with the
const keywords. The
var keyword is limited to function scope, meaning that new scope can only be created inside functions.
// standalone block scope
Function and block scopes can be nested. In such a situation, with multiple nested scopes, a variable is accessible within its own scope or from inner scope. But outside of its scope, the variable is inaccessible.
A Simple Example to Help Visualize Scope
On the other hand, the world’s oceans can’t be defined as having local scope, because they actually wrap all local objects — continents, countries, and cities — and thus, their scope is defined as global. Let’s visualize this in the next example:
var locales = europe: function() // The Europe continent's local scope var myFriend = "Monique"; var france = function() // France country's local scope var paris = function() // The Paris city's local scope console.log(myFriend); // output: Monique ; paris(); ; france(); ; locales.europe();
myFriend variable is available from the
paris function, as it was defined in the
france function’s outer scope. If we swap the
myFriend variable and the console statement, we’ll get
ReferenceError: myFriend is not defined, because we can’t reach the inner scope from the outer scope.
Back to the given metaphor, let’s say I want to find a friend of mine whose name is Monique. I know that she lives in Paris, so I start my searching from there. When I can’t find her in Paris, I go one level up and expand my searching in all of France. But again, she’s not there. Next, I expand my searching again by going another level up. Finally, I find her in Italy, which in our case is the local scope of Europe.
In the previous example, my friend Monique is represented by the variable
myFriend. In the last line we call the
europe() function, which calls
france(), and finally when the
This type of lookup is called lexical (static) scope. The static structure of a program determines the variable scope. The scope of a variable is defined by its location within the source code, and nested functions have access to variables declared in their outer scope. No matter where a function is called from, or even how it’s called, its lexical scope depends only on where the function was declared.
Now let’s see how the new block scope works:
function testScope(n) if (true) const greeting = 'Hello'; let name = n; console.log(greeting + " " + name); // output: Hello [name] console.log(greeting + " " + name); // output: ReferenceError: greeting is not defined testScope('David');
In this example, we can see that the
name variables declared with
let are inaccessible outside the
Let’s now replace the
var and see what happens:
function testScope(n) if (true) var greeting = 'Hello'; var name = n; console.log(greeting + " " + name); // output: Hello [name] console.log(greeting + " " + name); // output: Hello [name] testScope('David');
As you can see, when we use the
var keyword the variables are reachable in the entire function scope.
var test = "I'm global"; function testScope() var test = "I'm local"; console.log (test); testScope(); // output: I'm local console.log(test); // output: I'm global
Even with the same name, the local variable doesn’t overwrite the global one after the execution of the
testScope() function. But this is not always the case. Let’s consider this:
var test = "I'm global"; function testScope() test = "I'm local"; console.log(test); console.log(test); // output: I'm global testScope(); // output: I'm local console.log(test); // output: I'm local (the global variable is reassigned)
This time, the local variable
test overwrites the global variable with the same name. When we run the code inside the
testScope() function, the global variable is reassigned. If a local variable is assigned without first being declared with the
var keyword, it becomes a global variable. To avoid such unwanted behavior, you should always declare your local variables before you use them. Any variable declared with the
var keyword inside a function is a local variable. It’s considered best practice to declare your variables.
Note: in strict mode, it’s an error if you assign value to variable without first declaring the variable.