Skip to content

Lexical Scope

Javascript is a lexically scoped language.

Lexical Scope (Static scope)

Lexical Scoping defines how variable names are resolved in nested functions: inner functions contain the scope of parent functions even if the parent function has returned.

Lexical scope can be deduced at compile-time (hence Static scope). Because of that we can derive the scope from reading the source code.

Example of Lexical scope

Example of dynamic scope (Lisp)

Here fun can either access x in dummy1 or dummy2, or any x in any function that call fun with x declared in it.

dummy1(); will print 5, dummy2(); will print 10.

JavaScript has 3 types of scope: Block scope, Function scope, Global scope. (Block came with ES6).

Block Scope

ES6 introduced: let and const. These two keywords provide Block Scope in JavaScript. Variables declared with let and const inside a { } block cannot be accessed from outside the block.

Variables declared with the var keyword can NOT have block scope. Variables declared inside a { } block can be accessed from outside the block.

Line 8 will print value 4. Since var is not block scoped.

Line 12 will throw ReferenceError since var is function scoped and cannot accessed outside function.

Both line 8, line 12 will throw ReferenceError. Since let is both block scoped and function scoped.

Function Scope

Variables defined inside a function are not accessible from outside the function.

Variables declared with var, let and const are quite similar when declared inside a function. They all have Function Scope.

Global Scope

Variables declared Globally (outside any function) have Global Scope. Global variables can be accessed from anywhere in a JavaScript program.

Variables declared with var, let and const are quite similar when declared outside a block. They all have Global Scope.

Inside functionfunction scopedfunction scopedfunction scoped
Inside blockfunction scoped or global scopedblock scopedblock scoped
Inside globalglobal scopedglobal scoped (does not attach to window)global scoped (does not attach to window)

Global Variables in HTML

In JavaScript, the global scope is the JavaScript environment.

In HTML, the global scope is the window object.

Global variables defined with the var keyword belong to the window object:

Global variables defined with the let keyword do not belong to the window object:


The var statement declares a function-scoped or globally-scoped variable.

Accessing a var before it is declared has the result undefined because of hoisting.

let and const

let and const declares a block-scoped local variable.

Accessing a let or const before it is declared throws ReferenceError because of TDZ. That doesn't mean it's not hoisted though.

Accessing foo in inner scope will result in ReferenceError. This happens because of TDZ. You can try to comment out let foo = "inner"; and see error goes away.

let foo = "inner"; will be hoisted inside the function scope. Hence it will create a TDZ.

Profile picture

I have a passion for all things web.