Quiz

Explain the concept of lexical scoping

Topics
JavaScript

TL;DR

Lexical scoping means that the scope of a variable is determined by its location within the source code, and nested functions have access to variables declared in their outer scope. For example:

function outerFunction() {
let outerVariable = 'I am outside!';
function innerFunction() {
console.log(outerVariable); // 'I am outside!'
}
innerFunction();
}
outerFunction();

In this example, innerFunction can access outerVariable because of lexical scoping.


Name lookup follows source nesting

Lexical scope is determined where functions and blocks are written, so lookup walks outward through those enclosing environments.

Lexical environment lookup

The call site's scope is not searched, which is why passing a function elsewhere does not change which outer variables it captures.

Lexical scoping

Lexical scoping is a fundamental concept in JavaScript and many other programming languages. It determines how variable names are resolved in nested functions. The scope of a variable is defined by its position in the source code, and nested functions have access to variables declared in their outer scope.

How lexical scoping works

When a function is defined, it captures the scope in which it was created. This means that the function has access to variables in its own scope as well as variables in any containing (outer) scopes.

Example

Consider the following example:

function outerFunction() {
let outerVariable = 'I am outside!';
function innerFunction() {
console.log(outerVariable); // 'I am outside!'
}
innerFunction();
}
outerFunction();

In this example:

  • outerFunction declares a variable outerVariable.
  • innerFunction is nested inside outerFunction and logs outerVariable to the console.
  • When innerFunction is called, it has access to outerVariable because of lexical scoping.

Nested functions and closures

Lexical scoping is closely related to closures. A closure is created when a function retains access to its lexical scope, even when the function is executed outside that scope.

function outerFunction() {
let outerVariable = 'I am outside!';
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
const myInnerFunction = outerFunction();
myInnerFunction(); // 'I am outside!'

In this example:

  • outerFunction returns innerFunction.
  • myInnerFunction is assigned the returned innerFunction.
  • When myInnerFunction is called, it still has access to outerVariable because of the closure created by lexical scoping.

Further reading

Exercises

Check your understanding
Beta
Check your understanding Exercise
Check your understanding Exercise

What does this code log?

const label = 'global';
function makeReader() {
const label = 'creation';
return function read() {
return label;
};
}
function invoke(reader) {
const label = 'call';
return reader();
}
console.log(invoke(makeReader()));