Call Stack in JavaScript

The call stack tracks currently executing JavaScript functions and determines where synchronous execution resumes. It is central to understanding how JavaScript evaluates nested calls before the event loop handles later work.

The call stack is a last-in, first-out structure used to keep track of active JavaScript function calls. When a function starts, a stack frame representing that call is pushed onto the stack; when the function returns, its frame is removed.

For nested synchronous calls, each new function is placed above the caller. The newest call executes first, and once it finishes, execution returns to the function underneath it. This gives JavaScript a precise location from which to continue synchronous execution.

In browser JavaScript, the call stack works alongside the runtime's task and microtask mechanisms. A timer callback or event handler does not normally execute immediately when scheduled; it becomes eligible for execution later, after the current stack has become empty and the runtime processes queued work.

A long-running synchronous function keeps the call stack occupied. While that JavaScript is running, queued callbacks cannot begin through the normal event-loop process, which is why excessive synchronous work can make a page unresponsive.

Key points

Interview questions

What is the call stack in JavaScript?

The call stack is a LIFO structure that tracks active function calls. Each function invocation creates a stack frame containing information needed to execute that call. When the function returns, its frame is removed. This lets JavaScript know where to resume synchronous execution.

How does the call stack relate to the event loop?

Synchronous JavaScript runs on the call stack. Asynchronous operations can arrange for callbacks or promise reactions to be queued for later processing. The runtime does not interrupt an actively executing synchronous stack just to run one of those callbacks. Event-loop processing can run queued work after the current stack has cleared.

What happens to the call stack during nested function calls?

The caller's frame remains on the stack while the callee is added above it. The callee executes first because it is the top frame. Once it returns, its frame is removed and execution continues in the caller. This repeats for deeper nesting until the original call eventually returns.

Why can synchronous JavaScript block user interactions?

A synchronous function occupies the call stack for as long as it runs. While that work continues, the JavaScript runtime cannot begin other queued JavaScript callbacks through the normal event-loop process. A sufficiently long computation therefore delays event handlers, rendering-related work, and other callbacks. Breaking work into smaller asynchronous chunks can allow the runtime to make progress between pieces of computation.

What is a stack overflow in JavaScript?

A stack overflow occurs when execution creates more active stack frames than the runtime can support. A common cause is recursion without a terminating condition, because each recursive call adds another frame before an earlier call can return. The exact limit is runtime-dependent, so code should not rely on a particular maximum depth. Recursive algorithms may need a safe base case or an iterative design when depth can become large.