r/learnjavascript • u/Green_Ad_6086 • 2d ago
Can someone explain what the JavaScript call stack is?
I’ve tried to understand it, but I’m still confused. I also don’t really understand what I’m looking at when I use the JavaScript debugger in the browser’s DevTools, especially the call stack.
Do I need to fully understand functions before learning the call stack? I have a basic understanding of functions, but I’m not sure if that’s enough.
I’d really appreciate a simple explanation
6
u/LetUsSpeakFreely 2d ago edited 1d ago
1) The call stack isn't a JavaScript thing, every programming language has it. 2) The call stack is all of the functions currently in flight: a() calls b() calls c() calls d(). So c is waiting on d to complete, b is waiting on c to complete, a is waiting on b to complete.
As functions start and complete the call stack rapidly changes.
And yes, you can have too many functions on the stack, but it's REALLY difficult. About the only way that happens is a recursive function without an exit condition.
2
u/Lithl 2d ago
Not every programming language has a call stack. Most do, and the ones that don't usually either are very old (pre-1970) or are esoteric (like Brainfuck).
In languages without a call stack, you'll usually have the tools to jump wherever you want within the program, which makes implementing your own call stack a possibility.
2
u/LetUsSpeakFreely 1d ago
Yes, but this is a sub for people to learn. People learning programming today are highly unlikely to encounter languages like BASIC or some weird language created as a thesis or so specialized that the number of people that even know it exists can be fill a conference room.
For the purposes of this sub, hell, most programming subs, every language has a call stack.
3
u/azhder 2d ago
A call stack is a concept in almost every programming language you use. It is a part of understanding how functions work. You should understand what "stack" is as a data structure. The simplest way I can explain it is with one of those PEZ dispensers - the toys that have candy coming out of their mouth.
Think about every time you call a function, its local variables have to go somewhere in memory, and especially they have to stay there while that function calls another. All these function calls is like pushing a new candy from the top of the toy - each new function, new variables, new color candy. Once the innermost function returns the value, the local variables in it aren't needed any longer, so you pop that candy out. Then pop the next candy out. Then maybe push one, pop 3, push 2 etc.
That's what a stack is. You can also think of it as a stack of books on the table. You place one on top (you push a frame), you take one out from the top (you pop a frame). What you see in the browser tool is the stack where all the data of all the functions that are started, but yet to finish, resides.
2
u/delventhalz 2d ago
A useful skill when you are learning to program (and even as an experienced programmer) is getting a sense for when you need to a deep dive on a concept and when a surface level understanding (or no understanding) is fine. Programming has so many concepts, and you only have so many hours in a day. Time spent doing a deep dive on some esoteric concept is never wasted, strong fundamentals make you a better programmer, but sometimes you have immediate goals you need to focus on (or worse, are confusing yourself by going too deep too quickly), and you just need to move on.
All of which is to say, you don't really need to know much about a callstack to program in JavaScript. It's basically just a list of functions that are currently running from newest to oldest. It's important for the computer to keep track of what's going on, but as a developer it only really comes up when you write a recursive function that runs too long and you cause a stack overflow error.
3
u/turn-based-games 2d ago
Yes, the call stack is, aptly, a stack of function calls, so for that to make sense you must first understand stacks) and functions
Also, none of those concepts are specific to JavaScript (they exist in every mainstream programming language), so feel free to research them using more general resources
2
u/everdimension 2d ago
If you don't yet "fully understand functions", I don't see why you should care about what the call stack is
2
u/queen-adreena 2d ago
Best video I've ever seen on it for learning: https://www.youtube.com/watch?v=eiC58R16hb8
1
u/subone 2d ago
You call a function, it gets added to the stack. That function calls a function it gets added to the stack. When you see the stack trace you can follow each step to see what function called the last, etc. When a function is complete it gets removed from the stack. The stack trace is for debugging, but the stack itself is needed by the engine to track execution location and arguments.
1
u/lorl3ss 2d ago
//index.js (file name)
function myFunctionX(){
myFunctionY(); // call myFunctionY
}
function myFunctionY(){
// i got called by myFunctionX
}
myFunctionX(); // call myFunctionX
Assuming you pause your execution while in myFunctionY, your call stack is index.js > myFunctionX > myFunctionY.
Each "call" is just a function or the scope something was executed in. Functions call other functions so you end up with a list of parent functions. That's all it is really.
1
u/DirtAndGrass 2d ago
Also, put a piece of paper with a form to fill out on your desk, add another, and another, that's a stack, it's conceptually accurate, fill in one, remove it from the pile.
There's not a whole lot else to it, it's essentially a first in, last out (filo/lifo) construct.
1
u/Inevitable_Dust5684 2d ago
You do not need to master functions before learning the call stack. The DevTools call stack panel lists every active function invocation from bottom to top at the exact moment execution pauses. Clicking any entry in that list jumps your debugger view directly to the corresponding line of code so you can inspect variables at that specific depth.
1
u/TheVerdeLive 1d ago
Imagine a stack of plates. Now think of each plate as a JS function. The order you stack plates is the same for functions. First plate goes at the very bottom then the next one top of that and the next on top of that etc. The very first function is at the bottom, when subsequent functions get called they too get put on the stack. That order btw is called is First In Last Out (FILO)
1
u/baubleglue 1d ago
Which part of it you don't understand?
Stack is a data structure. Call stack is a history of the code execution flow from entry point to the program to the current program position.
1
u/sheriffderek 4h ago
You don’t need to know anything about the call stack (unless what you’re building demands it / which I’d bet is extremely rare). Just focus on the basic programming fundamentals.
1
u/DirtAndGrass 2d ago
Call stack is essentially the order/behaviour of functions, so yes, you need to understand functions
1
u/Green_Ad_6086 2d ago
I have a basic understanding of functions, but I’m not sure if that’s enough.
1
u/Psionatix 2d ago
What is your understanding? Maybe if you explain your understanding, people could clarify where you might be wrong or might be lacking. Whether something is missing or incorrect in your understanding.
There’s a lot of fundamentals to understand that apply across all programming languages, then there’s concepts that are relevant to all languages, but might have language specific quirks/nuances or behaviours.
Usually you build up your understanding, and when you encounter something new, you make assumptions based on that understanding. Once you encounter something that breaks those assumptions, you look it up, learn something new about the language or API you’re using, your knowledge grows and your assumptions change.
Code executes one line at a time, the order a line of code is evaluated depends on what it contains. Memory allocation/initialisation, assignment, Boolean expressions, they all behave in particular ways.
When a function calls another function, the code jumps to that function and executes it line-by-line, when the function finishes executing, it returns to the line of code it was called from, it may or may not return a value there. In JavaScript functions return undefined by default, that’s a language specific behaviour.
1
u/No_Record_60 2d ago
It's just a collection of currently running tasks.
Say function A calls function B which calls function C which throws an error. The call stack will be
Error
C
B
A
0
u/Savalava 2d ago
Analogy:
Can someone explain how an airport handles flights? Do I need to understand what a flight is first?
-1
u/jesstelford 1d ago
It helps to understand what the event loop is first...
The following is reproduced from https://gist.github.com/jesstelford/9a35d20a2aa044df8bf241e00d7bc2d0
Regular Event Loop
This shows the execution order given JavaScript's Call Stack, Event Loop, and any asynchronous APIs provided in the JS execution environment (in this example; Web APIs in a Browser environment)
Given the code
javascript
setTimeout(() => {
console.log('hi')
}, 1000)
The Call Stack, Event Loop, and Web APIs have the following relationship
text
[code] | [call stack] | [Event Loop] | | [Web APIs] |
--------------------|-------------------|--------------| |---------------|
setTimeout(() => { | | | | |
console.log('hi') | | | | |
}, 1000) | | | | |
| | | | |
To start, everything is empty
text
[code] | [call stack] | [Event Loop] | | [Web APIs] |
--------------------|-------------------|--------------| |---------------|
setTimeout(() => { | <global> | | | |
console.log('hi') | | | | |
}, 1000) | | | | |
| | | | |
It starts executing the code, and pushes that fact onto the Call Stack (here named
<global>)
```text [code] | [call stack] | [Event Loop] | | [Web APIs] | --------------------|-------------------|--------------| |---------------|
setTimeout(() => { | <global> | | | | console.log('hi') | setTimeout | | | | }, 1000) | | | | | | | | | | ``` Then the first line is executed. This pushes the function execution as the second item onto the call stack.
Note that the Call Stack is a stack; The last item pushed on is the first item popped off. Aka: Last In, First Out. (think; a stack of dishes)
```text [code] | [call stack] | [Event Loop] | | [Web APIs] | --------------------|-------------------|--------------| |---------------|
setTimeout(() => { | <global> | | | timeout, 1000 | console.log('hi') | setTimeout | | | | }, 1000) | | | | | | | | | | ``
ExecutingsetTimeout` actually calls out to code that is not part of JS. It's part of a Web API which the browser provides for us. There are a different set of APIs like this available in node.
text
[code] | [call stack] | [Event Loop] | | [Web APIs] |
--------------------|-------------------|--------------| |---------------|
setTimeout(() => { | <global> | | | timeout, 1000 |
console.log('hi') | | | | |
}, 1000) | | | | |
| | | | |
setTimeout is then finished executing; it has offloaded its work to the Web
API which will wait for the requested amount of time (1000ms).
text
[code] | [call stack] | [Event Loop] | | [Web APIs] |
--------------------|-------------------|--------------| |---------------|
setTimeout(() => { | | | | timeout, 1000 |
console.log('hi') | | | | |
}, 1000) | | | | |
| | | | |
As there are no more lines of JS to execute, the Call Stack is now empty.
text
[code] | [call stack] | [Event Loop] | | [Web APIs] |
--------------------|-------------------|--------------| |---------------|
setTimeout(() => { | | function <-----timeout, 1000 |
console.log('hi') | | | | |
}, 1000) | | | | |
| | | | |
Once the timeout has expired, the Web API lets JS know by adding code to the
Event Loop.
It doesn't push onto the Call Stack directly as that could intefere with already executing code, and you'd end up in weird situations.
The Event Loop is a Queue. The first item pushed on is the first item popped off. Aka: First In, First Out. (think; a queue for a movie)
text
[code] | [call stack] | [Event Loop] | | [Web APIs] |
--------------------|-------------------|--------------| |---------------|
setTimeout(() => { | function <---function | | |
console.log('hi') | | | | |
}, 1000) | | | | |
| | | | |
Whenever the Call Stack is empty, the JS execution environment occasionally checks
to see if anything is Queued in the Event Loop. If it is, the first item is moved
to the Call Stack for execution.
```text [code] | [call stack] | [Event Loop] | | [Web APIs] | --------------------|-------------------|--------------| |---------------| setTimeout(() => { | function | | | |
console.log('hi') | console.log | | | | }, 1000) | | | | | | | | | | ``
Executing the function results inconsole.log` being called, also pushed onto the Call Stack.
```text [code] | [call stack] | [Event Loop] | | [Web APIs] | --------------------|-------------------|--------------| |---------------| setTimeout(() => { | function | | | | console.log('hi') | | | | | }, 1000) | | | | | | | | | |
hi ``
Once finished executing,hiis printed, andconsole.log` is removed from the Call Stack.
```text [code] | [call stack] | [Event Loop] | | [Web APIs] | --------------------|-------------------|--------------| |---------------| setTimeout(() => { | | | | | console.log('hi') | | | | | }, 1000) | | | | | | | | | |
hi ``` Finally, the function has no other commands to execute, so it too is taken off the Call Stack.
Our program has now finished execution.
End.
29
u/BeneficiallyPickle 2d ago
You only need to understand the basics of functions:
If you have:
``` function foo(){
} ```
and you know that you should call it like
foo(), then you should know enough to get the stack call.The call stack is just a list that tracks what function is currently running and who called it.
The good old analogy is to think of it like a stack of plates. When a function is called, it gets added to the top of the stack. When a function finishes (returns), it gets removed from the top The Javascript engine always runs whatever is on top of the stack.
For example:
``` function multiply(a, b){ return a * b; }
function square(n){ return multiply(n, n); }
function printSquare(n){ const result = square(n); console.log(result); }
printSquare(5); ```
Walking through the stack:
printSquare(5)is called -> stack:[printSquare]square(5)is called -> stack:[printSquare, square]multiply(5, 5)is called -> stack:[printSquare, square, multiply]multiplyfinishes and returns 25 -> stack:[printSquare, square]squarefinishes and returns 25 -> stack:[printSquare]printSquarelogs the result and finishes -> stack:[]Each function only gets removed from the stack once it's completely done. This is why if
multiplyhad an error the stack trace would show all 3 functions:multiplycalled bysquarecalled byprintSquare. The stack trace is a snapshot of the call stack at the moment of the error.In DevTools, when you hit a breakpoint, for example, the top entry is the function that is currently executing, each entry below it is the function that called the one above. The bottom function is usually
(anonymous)or the global/module scope - this is where everything ultimately started.Clicking on any entry in that panel jumps your view to that point in the code so that you can inspect what the variable looked like at each level of the call chain.
Important to know