JavaScript's Call Stack

Share this video with your friends

Social Share Links

Send Tweet
Published 8 years ago
Updated 5 years ago

JavaScript has a concurrency model based on an "event loop". Yet, we know that JavaScript is single-threaded, which means only one task can happen at a time. To understand how JavaScript has a concurrent model yet is single threaded, we'll take a look at how the browser is working to interpret your JavaScript.

Specifically, we'll start by looking at the Stack implemented by browser engines (e.g. V8 or SpiderMonkey). The JavaScript engines use the call stack to keep track of what functions are running -- a function is added to a stack when the engine reaches a function that needs to be executed, and it cleared from the stack when the function returns.

[00:00] JavaScript has a concurrency model based on an event loop. Concurrency just means more than one task is running at once, yet we know that JavaScript is single-threaded, which means only one task can happen at a time. So to understand how JavaScript has a concurrent model, yet is single-threaded, we'll take a closer look at how the browser's working to interpret your JavaScript.

[00:18] Every browser has a JavaScript engine. For Chrome that's the V8 engine, for Firefox that's SpiderMonkey, and this engine is a virtual machine that interprets your code. Every browser vendor implements and optimizes it differently, but [inaudible] gives us a theoretical model of what the implementation looks like. There's a stack which more often out of the call stack, and a heap which is just a large, mostly unstructured region of memory. You also see an event table, a task queue, and an event loop.

[00:46] The interpreter makes use of these to keep track of what code it should run. As a JavaScript engine processes your JavaScript line by line, it uses a call stack to essentially keep track of what functions are running. Think of the call stack as a stack of plates. Last one to get put on top is the first one to get taken off. So a function is added to the stack when the engine reaches a function that needs to be executed, and is cleared from the stack when the function returns.

[01:12] Let's take a look at a live example in code, and use Chrome dev tools to inspect the call stack in real time. So what I have here is a very basic index.html file, and in the script tag, I'm passing a main.js file. Main.js file is where we'll write out code. Let's have a result variable and set it equal to its function first, and we pass in 8.

[01:35] Let's go ahead and define this function first. The function will take an argument x, and return another function called second, and multiply that argument by 2. Then the function second will take the argument you passed in, and return another function third that will take the argument that you passed on, and will add 16, and this function third will take the argument that you passed in, and now third will return whatever you passed in times 3.

[02:08] So let's go ahead and actually throw a debugger in here, so we can walk through the program and also console.log the results so we can see it in the console. All right, let's go ahead and move to our browser.

[02:25] I've already gone ahead and pulled it up in my browser, so I'm going to go ahead and open Chrome dev tools. We're going to start with our sources tab, and what we're going to do is walk through this program function-by-function as it gets executed, and we'll also be watching the call stack.

[02:44] When I refresh the page it will start with the debugger, and these are all just function declarations, so nothing gets actually executed until we come to this line here, and first gets executed. So watch what happens. All right, when we step into first, first gets put on the call stack. Now, because first returns another function second, watch what happens -- second gets put on the call stack.

[03:09] Now second returns another function third, so third gets put on the call stack. All right, so neither of these have returned, so they're all on the call stack still.

[03:19] But watch what happens when third returns. All right, third gets popped off the call stack, and since third returned, second can return. So second gets put off the call stack, and now first can finally return and so first comes off the call stack.

[03:37] Now our call stack is empty, and if we play this and go to our console, we'll see 96, which is exactly what we expected.

jason huang
jason huang
~ 7 years ago

hi, I notice that when the program stops at the debugger the stack has a anonymous function what is that? thanks

-kuolun

Markdown supported.
Become a member to join the discussionEnroll Today