JavaScript Scopes: Exploring Local, Function, Block, Global, and Nested Scopes

The location where you declare a variable will affect where it can be used within your code. This is known as the variable's scope.

There are two kinds of scope – global scope and local scope.

Local Scope

Variables that are usable only in a specific part of your code are considered to be in a local scope. These variables are also called local variables.

In JavaScript, there are two kinds of local scope: function scope and block scope.

Let’s talk about function scopes first.

Function Scope

When you declare a variable in a function, you can access this variable only within the function. It cannot be accessed outside of the function in which it was declared.

In the example below, the variable area is in the getArea() scope:

function getArea(width, height) {
  let area = width * height;
  console.log(area);
}

getArea(3, 2); //6
console.log(area); //Error, area is not defined

The interpreter creates local variables when the function is run, and removes them as soon as the function has finished its task. This means that:

  • If the function runs twice, the variable can have different values each time.

  • Two different functions can use variables with the same name without any kind of naming conflict.

Block scope

When you declare a variable with const or let within a curly brace ({}), you can access this variable only within that curly brace.

In the example below, you can see that area is scoped to the curly brace:

{
  const area = 3 * 6;
  console.log(area); // 18
}

console.log(area); // Error, area is not defined

The block scope is a subset of a function scope since functions need to be declared with curly braces.

Global Scope

If a variable is declared outside all functions or curly braces ({}), it is said to be defined in the global scope.

Once you’ve declared a global variable, you can use that variable anywhere in your code, even in functions.

const area = 18;

function getArea() {
  console.log(area);
}

console.log(area); // 18
getArea(); // 18

Although you can declare variables in the global scope, it is advised not to.

Global variables are stored in memory for as long as the script is running. This means they take up more memory than local variables. Scripts that require a lot of memory can perform slower, which in turn takes longer to respond to the user.

It also increases the risk of naming conflicts. This is because there is a chance of naming collisions, where two or more variables are named the same.

If you declared your variables with const or let, you would receive an error whenever a name collision happens. This is undesirable.

// Don't do this!
let something = "Just a string";
let something = "Just another string"; // Error, thing has already been declared

If you declare your variables with var, your second variable overwrites the first one after it is declared. This is also undesirable as you make your code hard to debug.

// Don't do this!
var something = "Just a string";
var something = "Just another string";
console.log(thing); // 'Just another string'

For these reasons, you should use local variables wherever possible.

If you forget to declare a variable using the let/const keyword, the variable will work, but it will be treated as a global variable (this is considered bad practice).

Functions do not have access to each other’s scopes

Functions do not have access to each other’s scopes when you define them separately, even though one function may be used in another.

In this example below, otherFunc does not have access to greet.

function sayHello() {
  const greet = `Hello`;
}

function otherFunc() {
  sayHello();
  console.log(greet); // Error, greet is not defined
}

Nested scopes

When a function is defined in another function, the inner function has access to the outer function’s variables.

However, the outer function does not have access to the inner function’s variables.

function outerFunction() {
  const outer = `I'm the outer function!`;

  function innerFunction() {
    const inner = `I'm the inner function!`;
    console.log(outer); // I'm the outer function!
  }

  console.log(inner); // Error, inner is not defined
}

Understanding scopes is important in JavaScript, but they seem to be confusing at first. I hope the article has helped you understand what they are.

Get my free, weekly JavaScript tutorials

Want to improve your JavaScript fluency?

Every week, I send a new full-length JavaScript article to thousands of developers. Learn about asynchronous programming, closures, and best practices — as well as general tips for software engineers.

Join today, and level up your JavaScript every Sunday!

Thank you, Taha, for your amazing newsletter. I’m really benefiting from the valuable insights and tips you share.

- Remi Egwuda