The Blog Image

JavaScript

Closures and Lexical Scoping

4/23/2023

A closure is the combination of a function bundled together (enclosed) with references to its surrounding state. (MDN)

Lexical Scoping

Lexical scoping is a programming language concept that determines the scope of a variable based on its place in the source code, rather than its place in the execution context. In other words, the scope of a variable is determined by the block of code in which it is declared, not by the function in which it is used.

Closure

In JavaScript, a closure is a function that retains access to variables in its lexical scope, even after the outer function has returned. This means that the inner function can still access and manipulate the variables of the outer function, even if the outer function has already completed its execution.

When a function is defined inside another function, the inner function forms a closure. This means that the inner function has access to the variables in its parent function’s scope, even after the parent function has finished executing. Closures are useful for creating private variables and functions, and for implementing the module pattern in JavaScript.

function makeCounter() {
  let count = 0

  return function () {
    return count++
  }
}

let counter = makeCounter()

console.log(counter()) // 0

Then, how does the anonymous function remember its lexical environment?

[[Environment]]

Every function has a hidden property called [[Environment]] , which stores the reference to the lexical scope where the function was defined. So, in the code above, the counter.[[Environment]] has the reference to the lexical scope which has the value of count.

Each time the counter function is called, a new lexical scope is created that references the lexical scope stored in the counter counter.[[Environment]] as an outer lexical scope. When we call the counter function, JavaScript will find the count variable. First, JavaScript tries to find it in its lexical scope. But, there is not the count variable. So, JavaScript now tries to find count variable in the outer lexical scope and found it! Now it’s time to increase the value of the count variable. And this operation works on the lexical scope where the variable is stored. So the counter function can remember the valule of count variable.

Note: memory leaks

One important consequence of closures is that they can create memory leaks. Because the inner function retains a reference to the outer function’s variables, those variables cannot be garbage collected until the inner function is also garbage collected. This means that if you are not careful, you can end up with a lot of unused memory in your application.

References

https://javascript.info/closure