Course contents
- 01Variables
- 02Primitive Data Types
- 03Operators
- 04Conditionals
- 05Arrays
- 06Array methods and properties
- 07Objects
- 08Functions
- 09Callbacks
- 10Arrow functions
- 11Promises
- 12Async and await
- 13Loops
- 14DOM Manipulation
- 15Syntax parser
- 16Execution context and hoisting
- 17Call stack
- 18WebAPI and setTimeout
- 19Closures
- 20Function Constructors and Prototypes
- 21By value vs by reference
Closures
Every execution context has their own memory space set up. This memory space can contain the values of the passed arguments, or variables defined within that function. This means that even after that certain function might have returned and popped off the stack, we still have access to its memory for a while!

When we invoked sayHi, we added the greet function to the call stack.

The greet function also returns a function! This function receives an argument, that we later pass when we invoke the sayHi function.
As the greet function returns, it gets popped off the stack. However, its memory space is still available for a while. Then, sayHi gets invoked and pushed to the stack.

In sayHi, we need to have access to the greeting variable. It can’t find that within that function, so it goes up the scope chain. When its code is invoked, and it sees the greeting variable, it goes up the scope chain, and there is an outer lexical environment reference to that variable. Although the execution context of greet is gone, the execution context of sayHi still has a reference to the memory space of its outer environment.

A closure is a function having access to the parent scope, even after the parent function has been popped off the stack. A closure makes sure that it “closes in” all the variables that it should have have access to, hence the name closure.
References and further reading
- MDN: ClosuresThe canonical explanation with examples.
- Wikipedia: ClosureThe idea beyond JavaScript.