DEV Community

Cover image for Lexical vs. In-Memory Scope in JavaScript
Gabrielle J.
Gabrielle J.

Posted on

Lexical vs. In-Memory Scope in JavaScript

In programming, the concepts of lexical and in-memory scopes are two important tenets used to determine where a variable can be used in a program. Every programming language has its own scoping rules – this article covers JavaScript’s rules.

Lexical Scope

A very efficient definition of scope is laid out by Oluwatobi Sofela:

Scope refers to the area where an item (such as a function or variable) is visible and accessible to other code.

An item is said to be lexically scoped when it's first declared. In other words, its accessibility is created at the same time it is created. Lexical scoping can help to avoid naming conflicts, and it keeps variables localized to where they are needed.

var hasLexicalScope;   // a variable

function example(){
  console.log('I have lexical scope as well')
}   // a function declaration

Enter fullscreen mode Exit fullscreen mode

Within the category of lexical scope, there are three sub-categories:

  • block scope (think, a conditional or a loop)
  • function scope
  • global scope

Variables defined in either a block of code or a function declaration can only be used in that block or function, because that's the area where they were created. Any attempt otherwise, will result in a reference error.

Conversely, if a variable is not block- or function-scoped, it has global scope -- it is accessible from anywhere in its program.

let isGloballyScoped = "example";
console.log(isGloballyScoped); // prints example


function isFunctionScoped() {
  let message = "I can only be accessed from inside my 
  function !";
}
console.log(message); // prints Reference Error: message is 
not defined 


if (1 === 2) {
  var isBlockScoped = "I can only be accessed from inside 
  my code block!";
}
console.log(isBlockScoped); // prints Reference Error:
isBlockScoped is not defined 

Enter fullscreen mode Exit fullscreen mode

In-Memory Scope

In-memory scope refers to the availability of a variable or function while it's being executed. This means, that when a function or a variable is running, its information is temporarily stored in memory, in a structure referred to as an execution context. In-memory scoping can make it easier to share data between different parts of the code.

If you've heard the term call-stack, you already known what an execution context is!

A variable can be accessed from any part of the code that is called by the same execution context. It's important to note that every time a function is called, a new execution context is created.

function outer() {
  const message = "Hello, world!";

  function inner() {
    console.log(message); // This will also log "Hello, world!"
  }

  setTimeout(inner, 1000); 
}

outer();

Enter fullscreen mode Exit fullscreen mode

In this example, the variable message is still declared inside the outer function, but it is also accessible inside the inner function, which is called by the setTimeout function after a delay of 1000 milliseconds. Since inner is called by the same call stack as outer, it can access the message variable even though it is not in its lexical scope.

To sum up, the main difference between lexical and in-memory scope is that lexical scoping is determined at compile-time and remains fixed at runtime, whereas in-memory scoping is determined at runtime and can be changed during the execution of the program.

I hope this article has provided you clarity on this crucial topic in computing, & thank you for reading!


Photo by Tim Mossholder from Pexels

Top comments (0)