Skip to main content

Scope and Scope Chain


Scope is the area of the program where the variable can be accessed. The scope of a variable is defined by its location within the code.

info

Scope is established at compile time but used at runtime. Which means scope of a variable is not determined by where the function is called, but by where the function is defined (i.e. where it is present lexically in the code).

What exactly is meant by creating a scope?
How closure scope creation is different from other types of scopes

Lexical Environment

(Improve below definition. explain when lexical environment is created here itself rather than in warning)

Lexical environment is the local memory of the function along with the reference to the lexical environment of its lexically parent function. Scope is internally stored in memory as part of the Lexical Environment.

It consists of two components:

  1. Environment Record: It stores all the local variables and function declarations within the function.
  2. Reference to the outer environment: It is a reference to the outer lexical environment.
ConceptWhat It Is?
ScopeThe set of variables/functions accessible in a given part of the code (based on where the code is written).
Lexical EnvironmentThe internal data structure that JavaScript uses to implement scope at runtime.

warning

A lexical environment is created when a function is defined, not when it's called and it happens in compilation phase. During this phase only, variables are allocated memory (in environment record) and hoisting is done.

When the function is called, its execution context is created and the previously created lexical environment is attached to this execution context.

Add images from browser dev tools showing all these lexical environments for nested functions (see end of namaste js video in references below)

Scope Chain

function outer() {
let x = 10;
function inner() {
console.log(x);
}
inner();
}

outer(); // 10
Draw and Import ipad images for scope chain

Types of Scope

Some of below maybe be same or invalid. Need to verify and correct them.
  1. Global Scope
  2. Module Scope
  3. Block Scope (https://youtu.be/lW_erSjyMeM?list=PLlasXeu85E9cQ32gLCvAvr9vNaUccPVNP)
  4. Function Scope
  5. Closure Scope
info

Script scope

When each of above scope is created, destroyed & what it stores

  1. Local Scope (common name for block and function scope)
  2. Lexical Scope (not an actual scope but a lookup rule implemented using scope chain i.e. reference to parent scope in lexical environment)

Global lexical environment vs Global scope

Both global lexical environment and global scope are created when the script is loaded in the browser. They both exist at the same time and are used to store global variables and functions in different ways.


Global Scope

In browsers, Global scope is usually represented by the window object which is used to store variables/functions which are accessible globally anywhere. Depending upon the type of script tag, the global scope can store variables/functions in different ways.

In a regular script, all var variables and functions are attached to the window object

var a = 10;
let b = 20;
const c = 30;
function foo() {
console.log("foo");
}
console.log(window.a); // 10
console.log(window.foo); // function foo() { console.log("foo"); }
console.log(window.b); // undefined
console.log(window.c); // undefined

However, module scripts script type="module" run in a separate module scope and do not attach variables to the window object. This is because module scripts are designed to be more encapsulated and avoid polluting the global scope.

// script type="module"
var a = 10;
let b = 20;
const c = 30;
function foo() {
console.log("foo");
}

console.log(window.a); // undefined
console.log(window.b); // undefined
console.log(window.c); // undefined
console.log(window.foo); // undefined

In both cases, let and const variables are not attached to the window object. This is because let and const variables are block-scoped and do not have a global scope.


Global Lexical Environment

Global Lexical Environment (GLE) is an internal JavaScript structure that stores global variables but separates var vs. let and const.

It stores var variables in the declarative environment record and let/const variables in the object environment record both of which are part of enviroment record defined above

var a = 10; //stored in declarative environment record
let b = 20; //stored in object environment record
const c = 30; //stored in object environment record
function foo() {
console.log("foo");
}
console.log(window.a); // 10
console.log(window.b); // undefined
console.log(window.c); // undefined
console.log(window.foo); // function foo() { console.log("foo"); }

GLE is the primary Storage for all top level variables and functions, and is used when any global variable is accessed. When the JavaScript engine processes var declarations and function declarations at the top level, it does two things:

  • It creates a binding in the GLE.
  • It also creates a property with the same name on the global object (window)

let and const bypass the window Object: Variables declared with let and const at the top level are stored in the GLE but are not automatically created as properties on the window object. They are still part of the global scope because the GLE is the first (and outermost) lexical environment in the scope chain when code is executing globally. You access them directly by their name.

Scope Resolution and the GLE: When the JavaScript engine tries to resolve a variable in the global scope, it starts by looking in the current lexical environment, which is the GLE. If it finds the variable there (regardless of whether it was declared with var, let, or const), it uses that binding. For var globals, finding it in the GLE also implies its existence as a window property.


FeatureGlobal ScopeGlobal Lexical Environment (GLE)
What is it?Everything accessible globallyInternal structure managing global variables
Stores var?✅ Yes (in window)✅ Yes (in Object Environment Record)
Stores let and const?✅ Yes✅ Yes (in Declarative Environment Record)
Stored in window object?✅ Yes (var)❌ No (let & const are not in window)
Has scope chain reference?❌ No✅ Yes (contains Outer Lexical Environment reference)

Section Doubts

  • Add declarative environment record and object environment record definitions in above section about Lexical Environment
  • What is usage of both global scope and global lexical environment?

Doubts

  • Lexical environment vs Variable environment. Is variable environment part of scope?
  • Where is lexical environment stored?
  • How variables are resolved using scope and lexical environment? explain with example
  • What kind of data structures are used to store environment record and reference to the outer environment?
  • Scope rules in arrow functions vs normal functions

References


Notes

Scope