JavaScript: How It's Made

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
today on how they do it JavaScript today we'll look at the computer science behind it so by the end of this video you should understand what a high-level single-threaded garbage-collected interpreted or just-in-time compiled prototype-based multi-paradigm dynamic language with a non-blocking event loop concurrency model really means if you're new you're like and subscribe because this is part 2 of the full javascript course on fire ship i/o last week we learn that javascript is a programming language based on the ECMO 262 spec but in order to really understand how it works in a computer system we need to go to the very bottom of the stack and by that I mean the bare metal CPU and memory on a machine this is a riddle computer on hearing Ishida the tips that make the computer work when you run a JavaScript program whether that be a web application in the browser or something server side with nodejs it needs to allocate memory on your RAM to store things for the runtime and for variables and objects that you reference in your code then it also needs a thread from your CPU to actually execute the instructions in your code but here's the thing as a JavaScript developer you never really have to think about this stuff because it's a high-level programming language but what do we really mean when we say high-level we're talking about the degree of abstraction or simplification that the language provides over the computer's hardware the lowest level language is machine code it's a numeric language that can be executed directly by the CPU but it would be extremely difficult to build a website with it because you would have to memorize a number for every single instruction that you want to run if we go up one level to assembly we get some syntactic sugar but each assembly language is specific to a particular CPU or operating system so we can move up another level to the C language which provides a modern syntax and the ability to write cross-platform programs but the developers still has to be concerned with low-level issues like memory allocation if we go one more step higher we reach the level of languages like JavaScript and Python that use abstractions like garbage collectors and dynamic typing to simplify the way developers write their applications so now that we're at this high level let's go ahead and unpack a few of the key terms related to JavaScript now there are two fundamental ways that we can translate the code written in a programming language to something that the CPU can actually execute one of them is called an interpreter and the other is called a compiler javascript is an interpreted language which means that it needs to have an in the environment to read the actual source code and executed we can demonstrate this by simply going into the browser and running some JavaScript code from the console now notice how the interpreter works he stays with you all the time and he translates each of your instructions immediately one by one now this differs from a compiled language like Java or C which will statically analyze all of your code in advance and then compile it down to a binary that you can actually run on the machine he takes you a complete list of instructions and without further ado translates the whole lot he then hands them back to you and goes away leaving you all on your own javascript was never designed to be a compiled language but in a few minutes we'll see how modern JavaScript engines can use features of a compiler to squeeze out additional performance from the language now another thing you might hear is that JavaScript is a dynamically typed language which tends to be a common characteristic with high-level interpreted languages and that just means that we don't use any explicit type definitions in vanilla JavaScript code we can look at this by comparing some statically typed dart code to some dynamically typed JavaScript in the dart code you'll notice that we're annotating things like integers and strings but the jas types are unknown or implicit and that's because the type is associated with a runtime value and not the actual variables or functions in your code now you might also hear that javascript is a multi-paradigm language the vast majority of general-purpose programming languages are multi-paradigm allowing you to combine styles from declarative functional approaches or imperative object-oriented approaches now one of the weirder things that you'll hear is that javascript is based on prototypal inheritance this course will have an entire video dedicated just to this topic but the general idea is that everything in JavaScript is an object and each object holds a link to its prototype and this creates a prototype chain where objects can inherit behaviors from other objects this can be a weird thing to get used to if you're familiar with class-based inheritance but it's one of the low-level concepts that makes JavaScript a very flexible multi-paradigm language now let's take a second to recap we know that javascript is a high-level interpreted dynamically typed multi-paradigm prototype based language but it's also a single threaded garbage collected non-blocking language with an event loop that can be just-in-time compiled the first set of definitions are mostly related to how javascript is laid out in ECMO - 6 - but it doesn't specify how the should be implemented how to manage memory and it doesn't even mention the event loop in the entire 800 page document so that means it's up to the browser vendors to handle these implementation details and two of the most popular implementations are spider monkey from Mozilla and v8 from Google the way they work is slightly different but they both do a thing called just-in-time compilation in the case of v8 it will compile all of your JavaScript down to native machine code before running it as opposed to interpreting bytecode line by line like a normal interpreter anyone up there fans anybody [Music] so these JavaScript engines don't fundamentally change the way developers write their code but the JIT compiler helps improve performance and browsers and on node but here's the thing javascript is a single threaded language so it can only do one computation at a time what I want you to do right now in this browser tab is open up the console with ctrl shift j and then create a while loop that never ends you'll notice that nothing works in this browser tab now if you try to click on something it will never capture that event because the single thread is stuck in that while loop and it can't move on to the next event go into the chrome task manager and you should see that browser tab using close to 100% of that CPU cores resources go ahead and end the process refresh the tab and then meet me back here to learn more about why that happened when executing your JavaScript code to regions of memory are allocated on the machine the call stack and the heap the call stack is designed to be a high performance continuous region of memory used to execute your functions when you call a function it creates a frame and the call stack that contains a copy of its local variables if you call a function within a function it will add another frame to the stack but if you return from a function it will pop that frame off the stack I think the best way to understand the call stack is to go through some of your own code frame-by-frame you can go into these sources tab in chrome dev tools and pause the execution of a script and then you can follow the call stack step by step if you look down here at the bottom you can see we're calling this function called current status when we call that function it then moves us up to the function body that first starts with a console log a console log is a one-and-done operation so it gets pushed onto the stack and then executed and immediately popped off the stack but then if we go to the next line you can see it returns a function that also calls a function for its argument so the next step is to call that happy function for the argument and you can see it gets pushed on to the call stack here and this happy function has its own local variable named foo which we can see on the local scope for this frame in the call stack and another nice thing is that you can see that this context for the function which in this case is the window so the call stack will push as many frames as it needs and then start popping them off as they're executed on the machine but what happens if we have a situation where the call stack never reaches a return statement for example a recursive function in the stack overflow function were incrementing a count for every frame in the call stack now eventually chrome will throw a call stack size exceeded error but an interesting thing to note here is that each frame in the call stack will contain a copy of the local count which we can inspect by traversing through the call stack but what happens when we run into something a little more complex like an object that might be referenced by multiple function calls outside of this local context that's when the heap comes into play it's a mostly unstructured memory pool where we store things like objects or primitive values inside of closures in this code example we have an object called my counter and then we're incrementing it with a function call from there we'll go over to the memory tab in chrome and take a heap snapshot and then we can search for that variable by name and see it in the heap the special thing about the heap is that it's garbage collected that means that v8 or the j/s runtime will try to clear up free memory when it's no longer referenced in your code that doesn't mean you don't need to worry about memory but it just means that you don't need to manually allocate and free up memory like you would in a C language so now that you know what the call stack and the heap are all about we can introduce the event loop now we already saw how a simple while loop can entirely break a single-threaded language so that leads to the question of how do we handle any kind of long-running task the answer is the event loop so let's go ahead and write our own from scratch in the most basic sense it's just a while loop that waits for messages from a queue then processes their synchronous instructions to completion in the browser you're already doing this all the time without even thinking about it you might set up an event listener for a button click when the user clicks that button it sends a message to the queue and then the runtime will process whatever JavaScript you defined as the callback for that event and that's what makes javascript non-blocking because the only thing it ever does is listen to events and handle callbacks so it's never actually waiting for the return value of a function the only thing it's actually waiting for is the CPU to process your synchronous code and for most things that's on a scale of microseconds now let's imagine the first iteration of the event loop it will first handle all of these synchronous code in the script after it's done running the synchronous code it checks if there are any messages or callbacks in the queue ready to be executed we can demonstrate this behavior very simply by adding a set timeout to the top of the script for 0 seconds now you might intuitively think that this timeout should be executed first because it's at the top of the file and it's a timeout for 0 seconds but the event loop won't actually get to it till it's done running this first iteration of synchronous code now what makes this so special is that you can offload long running jobs two completely separate thread pools in the browser you might make an HTTP call that takes a few seconds to resolve or I know jsut might need to interact with the file system but you can do these things without blocking the main JavaScript thread and that's almost everything you need to know about the event loop but javascript had to go and make things a little more weird with the introduction of promises and the micro task queue if we go back to our script and add a promise resolve after the set timeout you would think that we have two asynchronous operations here with zero delay so the set timeout would fire first and in the promised second but there's actually this thing called the micro task queue for promises which has priority over the main task queue used for Dom API s and set timeouts and things like that that means the handler for the promise will be called back first in this case as the event loop goes through an iteration it will first handle the synchronous code then it's going to go to the micro task queue and handle any of the callbacks that are ready from your promises and lastly it will finish up by running the callbacks that are ready from your set timeouts or Dom API s and that's how JavaScript works I guess if all this sounded overwhelming to you don't worry too much because you don't really need to know any of it to start building stuff with JavaScript in the upcoming videos in this series we'll look at the practical applications of JavaScript as they relate to building real products so make sure to subscribe and follow along with the source code on by airship IO thanks for watching and I will talk to you soon [Music]
Info
Channel: Fireship
Views: 817,697
Rating: undefined out of 5
Keywords: JavaScript, webdev, tutorial, js, ecmascript, how its made, how it works javascript, computer science, compsci, event loop, js event loop, js language, programming, programming language, ram, cpu, c language, v8, chrome, mozilla spidermonkey, chrome v8, java script, vanilla js, weird javascript course, call stack, heap, interpreter vs compiler, jit
Id: FSs_JYwnAdI
Channel Id: undefined
Length: 10min 53sec (653 seconds)
Published: Tue Jul 02 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.