JavaScript Scope Tutorial

In this section, we will learn what the scope is and how to use it in JavaScript.

What is Scope in JavaScript?

In JavaScript, scope is the area in which an identifier (variable or function names) is accessible. This means outside of the scope of an identifier, it’s like the identifier does not exist at all.

Scope of Variables in JavaScript:

In short, an identifier can have one of these scopes in JavaScript:

  • Global Scope
  • Function Scope
  • Block Scope

Global Variables in JavaScript: Global Scope

An identifier that is defined outside of any block `{}` has the global scope. A global scope variable is accessible (can be invoked) inside the body of any block.

Example: creating global scope variables in JavaScript

let firstName = "Jack";
const lastName = "Bauer";
function sayHi(){
  console.log(`Hello ${firstName} ${lastName}`);
}
sayHi();

Output:

Hello Jack Bauer

In this example, the two variables `firstName` and `lastName` are defined outside of any functions (any block) and so the scope of these two variables is global. Also, the function `sayHi` is declared outside of any function and so that has the scope of global as well.

This means the `firstName`, `lastName` and the `sayHi` are accessible within the body of any block in this program. That’s how we could access the two variables `firstName` and `lastName` in the body of the `sayHi()` function.

Local Variables in JavaScript: Function Scope

A variable that is declared via the `var` keyword and inside the block of a function has the scope of that function. This means the variable is only accessible within the body of that function. So if an external function tries to access the value of a variable with this type of scope, it will get a reference error.

Notes:

  • When declaring a variable via the keyword `var`, even if that variable is declared inside an inner block (like in an if statement) in the function, it still has the scope of the function. This means we can access the variable anywhere between the opening and the closing braces `{}` of that function.
  • Also, identifiers that are created via the `let` and `const` keywords inside the body of a function but not in an inner block in the function have the scope of that function as well. (Declaring a `const` or `let` identifier in an inner block will have block-scope instead of function scope as you’ll soon see an example of it in this section).
  • Also, declaring a function inside the body of another function makes the inner function to have the function-scope. This means the inner function is only accessible inside the body of the enclosing function and not outside of it. (Actually, we can return an inner function as the output of the enclosing function and so allow the access from external resources to the inner function. This is a lengthy topic and is covered in the closure section).

Example: creating function scope variables in JavaScript

function sayHi(){
  var firstName = "Jack";
  let lastName = "Bauer";
  console.log(`Hello ${firstName} ${lastName}`);
}
sayHi();
function boo(){
  console.log(`${firstName} ${lastName}`);
}
boo();

Output:

Hello Jack Bauer

Uncaught ReferenceError: firstName is not defined

First, when we called the `sayHi()` function, the ` console.log(`Hello ${firstName} ${lastName}`);` statement ran without any problem because both `firstName` and the `lastName` were declared in the body of the function and had the scope of that function.

But when we called the `boo()` function to access these two variables, we got a reference error. This is because the scope of the two variables is local to the `sayHi` function only. So basically, we were trying to access to variables that didn’t exist from the perspective of the `boo()` function.

JavaScript Block Scope: JavaScript let and const

An identifier that is created via the `let` or `const` keyword and inside a pair of braces `{}` has the scope of that block.

This means that identifier is only accessible within the pair of braces `{}` in which it is being declared. Outside of this pair of braces it’s as if the identifier did not exist.

Example: creating block scope variables in JavaScript via let and const

{
 let fisrtName = "John";
 const lastName = "Doe";
} 
console.log(fisrtName, lastName);

Output:

Uncaught ReferenceError: fisrtName is not defined

Here the two variables `fistName` and `lastName` are declared inside a block and so their scope is only limited to that block.

For this reason, when we attempted to access the value of these two variables, we got a reference error.

So a block scope identifier is only accessible within the block in which it is declared.

Example: block scope in JavaScript

 
{
 let fisrtName = "John";
 const lastName = "Doe";
 console.log(fisrtName, lastName);
} 

Output:

John Doe

Notes:

  • There’s a concept called Temporal Dead Zone or TDZ for short that is related to variables that are created via `let` or `const` keyword. Please check the next section to learn about this concept. It’s an important topic.
  • Also, make sure you read the hoisting section as well. It will show you how scopes relate to each other.

Automatically Global Scope Variable in JavaScript

You should know that if you create a variable without the use of `var`, `const`, or `let` keyword, that variable becomes a global variable immediately, even if the variable is declared inside a function or an inner block!

Example: creating automatically global scope variable in JavaScript

function funcOne(){
  fullName = "John Doe"; 
}
function funcTwo(){
  console.log(fullName);
}
funcOne(); 
funcTwo();

Output:

John Doe

Here inside the body of the funcOne() function we’ve created a variable named `fullName` but without the use of either `var`, `const`, or `let` keyword. For this reason, even though the variable is declared inside the body of the `funcOne()`, it becomes a global variable automatically and is accessible in the body of other functions.

That’s why we could access the variable in the body of the funcTwo() function as well.

Lexical Scope in JavaScript

Lexical scope in JavaScript relates to the position where we declare a variable. Lexical scope basically means a variable that is declared outside of any function and block, is accessible inside of any function, but the reverse is not true. This means if there’s a variable inside the body of a function, that cannot be accessed outside of that function anymore (Because as we know it now, its scope becomes limited to its enclosing function).

Example: using lexical scope in JavaScript

let fullName = "John Doe"; 
function funcOne(){
  console.log(fullName); 
}
function funcTwo(){
  console.log(fullName);
}
funcOne(); 
funcTwo();

Output:

John Doe

John Doe

Here, the only reason we could access the `fullName` variable is because its lexical scope is set to global and so it is accessible inside the body of any function in this program.

Difference between Local and Global Variable

A global scope variable is by definition global and so it is accessible in every function and blocks in a program.

On the other hand, a local scope variable is local to the body that it was declared and hence it can’t be accessed outside of that block.

Leave a Reply