Mastering JavaScript Section 1: Critical Concepts | Steven Hancock | Skillshare

Playback Speed


1.0x


  • 0.5x
  • 0.75x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 1.75x
  • 2x

Mastering JavaScript Section 1: Critical Concepts

teacher avatar Steven Hancock, Founder All Things JavaScript

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

    • 1.

      JavaScript Critical Concepts Introduction

      1:31

    • 2.

      The JavaScript Runtime Environment

      6:13

    • 3.

      Understanding the JavaScript Engine

      6:07

    • 4.

      The Memory Heap and Call Stack

      13:54

    • 5.

      Understanding Garbage Collection

      7:03

    • 6.

      Removing Event Listeners to Help with Garbage Collection

      5:52

    • 7.

      Understanding the Event Loop

      7:34

    • 8.

      The Node Runtime Environment

      2:25

    • 9.

      Exercise Start: Exploring Call Stack and Event Loop

      3:01

    • 10.

      Exercise End: Exploring Call Stack and Event Loop

      4:06

    • 11.

      How JavaScript Evolves

      8:23

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.

77

Students

--

Projects

About This Class

This course represents the first section in Mastering JavaScript. In this course we will cover critical concepts. This course may not delve into the JavaScript language much, but it will indeed answer many questions about how JavaScript works and why certain things happen. Every top JavaScript programmer should understand these basic but important concepts.

In this course we cover the following critical concepts:

  • The JavaScript Runtime Environment
  • The JavaScript Engine
  • The Memory Heap and Call Stack
  • Garbage Collection
  • Removing Event Listeners to Help with Garbage Collection
  • The Event Loop
  • The Node Runtime Environment
  • How JavaScript Evolves

Understanding these critical concepts are important to put you in the top of all JavaScript developers, so jump in and get started.

Prerequisites and Set Up: The prerequisites for this course are pretty basic. You do need to know how to enter run JavaScript. It does help to understand some basics about the language so you can apply the concepts taught.

The setup is pretty easy. We aren't using any libraries or anything like that, so all you will need is a text editor and a browser. The majority of the JavaScript code that we write we will be run in a browser. There is a mention of Node.js, but code will be run in a browser. I will be using Chrome.

For a code editor I will be using Visual Studio Code. This is a free, cross platform editor that is pretty popular, so if you aren't currently using visual studio code and would like to during this course, you can download it here.

Once you have completed this course, I invite you to move on to Mastering JavaScript Section 2: Critical Fundamentals.

Meet Your Teacher

Teacher Profile Image

Steven Hancock

Founder All Things JavaScript

Teacher

I have 20+ years experience in training and product development and 15+ years using JavaScript. I started learning JavaScript when it was a new language used for minor affects on web pages. The growth and ubiquitous nature of JavaScript both excites and inspires me.

Currently I am the President and Lead Trainer of All Things JavaScript, a resource for anyone and everyone that hopes to increase their JavaScript skills. Our goal is to assist in the journey from JavaScript novice to expert.

I have been the co-owner and President of Rapid Intake, an eLearning firm. The company was an ideal place to put my training and development skills to work. While there I managed all development and professional service related activities. I was heavily involved in the initial development ... See full profile

Level: All Levels

Class Ratings

Expectations Met?
    Exceeded!
  • 0%
  • Yes
  • 0%
  • Somewhat
  • 0%
  • Not really
  • 0%

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.

Transcripts

1. JavaScript Critical Concepts Introduction: Welcome to this section on critical concepts in JavaScript. In this section, we're going to deal with what I think are critical concepts about the language and how JavaScript works. Now some of you may want to jump ahead two sections that focus more on the language aspect of JavaScript. But I would urge patients, these concepts are critical. Now, as you start in this section, some of the concepts may seem basic because they are. But even if you've been working with JavaScript for awhile, I'm sure you will learn something. So stick with it. Now, why are these concepts critical? Why is it important to understand how the language works? Because a critical part of any good developer's understanding is knowing why you do certain things. The y makes it possible to adjust patterns or code to fit your specific needs. The y facilitate critical thinking. And these concepts provide the why for many things we do in JavaScript that we will talk about later on. In fact, as a part of later sections, you may want to come back and revisit some of these topics, such as the event loop when dealing with asynchronous code. So it's important to spend some time talking about the JavaScript engine, the call stack, the memory heap. The fact that JavaScript is single threaded, the runtime environment and the event loop. So let's jump into it. 2. The JavaScript Runtime Environment: In order for us to make use of JavaScript, we need an environment where it will run. Now, JavaScript doesn't require a lot of tools in order to write code. In fact, we can just open a simple text editor and begin writing JavaScript. But in order for that code to make sense or to do anything, we need to make the code available to a JavaScript runtime environment. Now there are two main runtime environments that make up the majority of the use of JavaScript, the browser, and NodeJS. So we can have JavaScript run and complete some task using either the browser or node. Now, these two are not the only environments we could use, but they are the most important and the most prevalent. Now there are some similarities between node and browsers, and then there are some differences. Let's talk about those briefly. First, both a browser and node is simply an application. In each case, they need to be installed on your computer to use them. We installed Node earlier in the course. When I start up a browser, in this case Chrome, I'm starting up that application from my computer. Now the same is true with node. We simply use it differently. We need to use it from the terminal or command prompt. And we don't usually use a GUI interface. For example, I can access node by typing that in. And now I have a node prompt. That's how I use node. Another similarity is that these applications, meaning both the browser and node, are written with the same computer language. Now in the case of Chrome and most browsers for that fact, the core of that application is written in C plus plus. The GUI is usually a different language, but the core is C plus plus. Now, the core of NodeJS is also written in C plus plus with some JavaScript code that acts as a wrapper for some of the commands we use. The code. Those two applications are written in the browser and node is very similar, but that is not what makes it possible for us to use JavaScript in each of those environments. In order for a JavaScript runtime environment to allow the use of JavaScript, it needs something to interpret the language, to read the JavaScript and translate it for the computer. That very important piece is called the JavaScript engine. Both a browser and node require a JavaScript engine in order to use JavaScript. Now the JavaScript engine is just a piece of the entire application. There are a lot of other pieces to a browser and there are lots of other pieces to node. Let's take a look at a diagram that illustrates the runtime environment for our browser. These are all the pieces we are going to be talking about because we interact with them when we use JavaScript in the browser. So if this whole thing represents the browser and what it contains, we can see that there are things that are not apart of the JavaScript engine, which is represented up here. We sometimes do things in JavaScript that make use of parts of the browser application that is not a part of the JavaScript engine. Now these other parts or pieces are some of the things that are different between a browser and known. For example, in a browser, we interact with the DOM, extensively represented here in the web APIs. Well, that is not something we do in Node. There is no DOM that is a part of node. However known makes it possible to do other types of tasks. Tasks that are required on a server, such as write a file to a hard drive or start a server. Those are things that we can't do in a browser. So there are some differences. Let's take a look at another difference really quick. So here in a browser, if I open up the console, I can display window. That displays the window object. This is the global environment that we're writing code in. When we're writing JavaScript is inside of the window. And there's a lot of associated with the window, which we can make use of. Now node doesn't have a window. If we type window here, uncaught reference, our window is not defined. However, we can type global. And we do get information about global. And this would be the equivalent to Window on the browser side. Now, of course, there are going to be similarities. For example, you can see setTimeout here within global. Settimeout is available in the browser as well. You can see it's not in the JavaScript engine. It's actually part of the web API. Same thing with node. It's not a part of the JavaScript engine, but we have access to it. And we can do something like console.log here. And just like we can do in a browser. Now, over the next several topics, we're going to be talking about these different parts of a browser as they are critical to understand. In order to effectively write, JavaScript. Node also has additional parts, but we will focus mostly on the browser. First off, we're going to talk about the JavaScript engine. 3. Understanding the JavaScript Engine: Simply stated, the JavaScript engine is a program that executes JavaScript code. So looking at our diagram, if we have some JavaScript code, the JavaScript engine is in charge. It is the only piece that knows what to do with the code. It translates it into something that the computer can understand. Now, initial JavaScript engines early on were interpreters, which means they would process the JavaScript code line by line, convert it to bytecode so it could run. Interpreters are quit to start running the code, which is something that was needed in the browser environment. But they can be slower overall when compared to compile the code. Compiled code is converting the program to machine code so that it runs optimized. The latest JavaScript engines are much more optimized. They use a combination of an interpreter and just in time, compilation or JIT compiler to optimize the code. This gets the best of both worlds. Jit compilation takes cold that can be optimized and compiles it. For example, if a piece of code runs a lot, it can be compiled to machine code. And then when that piece of code does run, it is optimized and therefore faster. Now, there are a number of JavaScript engines. The one that is probably the most well-known is the V8 engine. This is the engine that is used in the Chrome browser and also in node. This engine was written by Google for Chrome using C plus plus. And it is open source. It is probably the most well-known engine because when it was built, it improved the speed of existing JavaScript engines. Google was using JavaScript to do some pretty amazing things at that time. Think about the different Google apps written with JavaScript. Anyway, they wanted it to be more performant. So they wrote the V8 engine to accomplish exactly that. Other JavaScript engines followed suit in order to make their engines more for performance as well. This improvement in performance is important to be aware of this idea of using a JIT compiler with an interpreter to help optimize the code. The reason this is important because we talk about writing code certain ways to make it more performance or avoid things in our code that could make it less performance. Many times it has to do with the way the JavaScript engine handles the code and is able to optimize it. Now, here are some other JavaScript engines you may have encountered. We've already mentioned V8 that it was open source, that was developed by Google. It's used in Chrome and NodeJS. Spider monkey. This was the first JavaScript engine, and today it's used in Firefox. And incidentally, the first JavaScript engine was written by Brendan Eich when he invented JavaScript, and as the story goes, did it in ten days. Now, JavaScript core, that's also open source and that was developed by Apple for Safari. So that's the engine that Safari uses. Another one we should probably mention is chakra. And this is used in Microsoft Edge. So Microsoft's JavaScript engine. Now, with all these different JavaScript engines in different browsers, how do we know that the JavaScript code we write will work the same way in each browser. Early in JavaScript's history, this was a real problem. There were differences. In those days. We spent a lot of time worrying about differences in browsers. Libraries like jQuery helps solve that issue and became very popular because of that. Now, because of these differences, there needed to be a standard and that is where Acme script comes in. This is a standard that JavaScript follows. An AGMA script is a specification that all JavaScript engines now follow. This allows multiple independent implementations, but it ensures that our code works the same. So when changes are made in the script standard, the Indians must be updated to support these changes. Some updates are faster than others. And that is why we have sites like this one. Can I use.com that tell us which browsers support certain implementations? So we can see the history of different browsers and when they started supporting ES modules in this example. Now, that is also why we make use of transpiler. A transpiler like babble, let you write code using the lightest Ekman scripts standard, but then outputs JavaScript code to an older standard. So an earlier form of JavaScript that older browser engines can run. This can also be called a compiler because technically you are compiling code to another form and older version of JavaScript. Alright, so that is enough about JavaScript engines. Now we need to get more into the details and talk about the heap and the call stack within the engines. These two things are used frequently when coding in JavaScript, even though you may not have known about it. 4. The Memory Heap and Call Stack: We're now going to dive into two features of the JavaScript engine that are important to understand, memory heap and the call stack. These are used throughout code execution. First I'll describe each one of them and then we'll see them in action to better understand how they are involved in code execution. Now, the memory heap, as the name indicates, has to do with memory allocation. Whenever you define a variable object function, anything like that in your code, there needs to be a place to store it. So like these variables here would be stored in the memory heap. Whenever a declaration is encountered, such as this, the value is placed in the memory heap, and then the location of that value is placed in the variable. Then whenever the code needs that value or the function or whatever is stored, it uses the memory location to look it up. Now the memory has a limited amount of memory, so complex programs that have a lot of variables and nested objects can chew up that memory. The JavaScript engine tries to make more memory available by clearing out data from the program that it determines is no longer necessary. This process is called garbage collection. There are things you can do as a programmer to assist in garbage collection. And there are things you could do that could hinder it. We will look at this in more detail in the topic on garbage collection. But for now, let's talk about the call stack. Anytime we run code, the call stack is used. It is simply a place in memory that keeps track of the function executing and the functions that are going to be executed after that. So the order in which these commands are executed. Now, each function is placed on top of the previous function. So the first function in is at the bottom of the call stack. And then as other functions are called, they're placed on top of it. So the call stack follows a first in, last out approach. Now as soon as the function or command is completed is removed from the call stack. Now, as you can see from the diagram, there is only a single call stack depicted. The JavaScript engine only has one call stack to deal with commands that are executing. That is because JavaScript is single threaded, a term you may have heard of. Now, a single thread means that the JavaScript engine can only execute one part of the program at a time. So the call stack deals with one command at a time. And as a result of this, JavaScript is synchronous. Commands can only be executed one at a time. You can probably see a possible problem with this. What if we invoke a function that requires a long time to run? How can we prevent that from blocking other code? For example, we want a user to be able to click on a button and not have to wait two seconds for some JavaScript to finish before it can respond to that button. Now, we'll dive into how this is handled and how the JavaScript engine deals with it when we talk about the event loop. And this is also why it's important to understand asynchronous JavaScript patterns in JavaScript. And that's one of the critical parts that we deal with in this course. Now, in our diagram, as you can see, we have some very simple code. Let's walk through it with the memory heap and the call stack illustrate how those are used in moving through the code. Basically what we're doing is we're declaring two variables, a and B. Then we have a function declared. And then we invoke that function here. Inside of the function, we call console log. We call setTimeout and pass in a function to setTimeout. The time for that is 0 milliseconds. And then we call console log again. So let's move through this. First we have the variable declarations. And so each one of those are going to be placed in the memory heap. There's 1 second. Now there is no specific order in how they are placed in the heap. They just need a reference to where that value is located. Then we have our function. And that's going to need to be placed in the heap as well. And there we've added that to the memory heap. Now if there were any variables declared inside of that function, those would need to be placed in there. Or if there are functions declared inside it, if there are other things inside that need to go into memory heap, that would need to happen. But now we encounter. The call to helloworld to that function. We're invoking it. So the JavaScript engine grabs that code from its memory location, and then it's able to begin executing it using the call stack. So the hello-world function is placed on the call stack that indicates where we are at within the code execution. So right now we are inside of function helloworld. We come to the first command in there, and that is a call to console.log. So we our invoking console dot log and that gets placed on the call stack. Now we're able to complete that command. And so once that command is complete, it is removed from the call stack and we're able to continue on. And we get to set timeout and setTimeout is added to the call stack. However, setTimeout is something that is a part of the web API, as you can see over here. So JavaScript doesn't need to do anything with that. So basically it gets rid of it. It sends it to the browser and says, Here, I've got to call the setTimeout. Here's the information. You go ahead and take care of it. And then to JavaScript engine forgets about it at that point, the web API, we'll set up a timer for that setTimeout and it will handle everything that needs to be handled with setTimeout. But at this point, the JavaScript engine as simply forgotten about it. It's not worried about it anymore. It simply continues on to the next command, which is another colleague, console.log. And so that gets added to our call stack. We're able to take care of that right away. We send a message to the console, which happens to be world. And then that's removed from the call stack. And then at that point we're at the end of the hello-world function. And so that is removed from the call stack. Now, you can see how the call stack could get built up with a number of things. If we had functions called inside of other functions. And the more we have nested functions like that, the more things that are going to be added to the call stack. And we'll build up on that call stack. Because until a function returns, until it completes, it cannot be removed from the call stack. Now with this whole illustration, I left setTimeout over there and said the JavaScript engine just forgot about it. Well, we're going to talk about that when we get to the topic on the event loop, because really it is the event loop and the message queue that deal with that, that deal with these web API items. So we'll discuss that in another topic. But before we move to the next topic, I want to address something we can encounter with the call stack is called Stack Overflow. And this is a condition you may have run into with your coding. This occurs when the call stack fills up because it can't remove commands and more keep getting added to it. I mentioned that nested functions could add a lot to the call stack. Well, it takes quite a bit in order for the call stack to fill up. But when it does fill up, it causes an error. Now, we can simulate this pretty easily with a recursive call. Now, recursion is simply when a function calls itself. And there are some situations where this is an advantageous pattern in JavaScript. But I want to show you the effects of what it does on the stack. So let's go ahead and set up a function that will illustrate this. This JavaScript file is attached to the HTML file. This one here that we're looking at previously. I'm just gonna put a function on it and call it self ramus. See what happens. So let me call it recursion. There's not necessary to call it that, but I'm gonna do that because I'm gonna be calling it. And then I'm going to set the number that is passed in equal to itself plus itself, something simple like that. And then here is where the recursion happens. We invoke itself from inside. So think about what this is going to do. The call stack. We're going to call recursion is going to place recursion on the call stack is going to get down to this line. And recursion is going to be called again, but the function hasn't completed, so it's not removed from the call stack. Another invocation of that is added to the call stack. And so it keeps adding recursion to the call stack until it builds up to the point that it can't add anymore. And that's where we get that stack overflow. Let me go ahead and invoke this. Going to pass in the number one. We'll save that. Now since I just have that attached to this HTML file, I'm just going to refresh that and see what happens. Let's open up the console and see what we have there. We have an air uncaught range. Our maximum call stack size exceeded. This is the air we would receive. If we had a stack overflow. Maximum call stack size exceeded, and that's what we're getting there. Now this is a simple problem to solve. All we have to do is make sure that eventually the functions start completing, that they return. And then it can remove them from the call stack. Eventually remove all of them from the skull call stack. Let's look at how that might be done. Let's say that if the number is greater than and I'm just going to put a large number here. I'm no idea how big it's going to be, but if it's greater than that, then I'm just going to log to the console. I want to see how big the number is, just for the fun of it. And then I'm going to return. So here's where we're returning from this function. So it will complete the function, we return here. It won't do this again. And it will complete that function that we're in. And so then it will unwind the call stack, each of those functions. We'll finally get to return because it'll get to the end of the function. And so the fact that the last time we call this, where the, where num is greater than this, that forces a return, doesn't call another one. And so all of those others that are in the call stack get to complete as well. And so then we don't get that stack overflow. Alright, let's look at that just one more time. I'm going to refresh here. I want to remember is not getting larger if I don't pass it back in when I call that function. So I want to make sure it's getting larger. There we go. Now we get a very large number coming out and we're no longer getting the stack overflow because was able to return. And then unwind all of those function calls that are in the stack. So that's what we're referring to when we're talking about StackOverflow. Alright, let's move on to the next topic. 5. Understanding Garbage Collection: In the previous topic, we mentioned garbage collection in connection with the memory heap. In a language like C, we have to allocate and release memory. Let's not so in JavaScript, but there still needs to be a mechanism for reclaiming memory. So we don't run out of memory and crash the system. Javascript handles the reclaiming of memory for us. Once a piece of information, an object or variable, is out of context and won't be used anymore. It's memory is reclaimed, so it can be re-used. This is called garbage collection. Let's take a look at how that works in the engine. Garbage collection takes place in the memory heap and it uses what is sometimes called a mark and sweep algorithm. It determines the objects that can be safely deleted from the memory heat by determining which things are reachable and which are unreachable. And then it sweeps through those that are unreachable. They're swept off and that memory is reclaimed. Let's take a look at how it works. Now, the garbage collector starts with the root or global object and moves to the objects referenced by them. And it moves from one object to another, identifying things that are referenced by something else. So basically, those things which are reachable, those things which are not reachable are now defined. And then everything that is unreachable, we now see a few things which are not linked or not reachable. Everything that is unreachable is cleared. It goes through and sweeps those off. They're gone. That memory can now be reclaimed and use for something else. Now, as you noticed in our explanation, order for information to be freed up and reclaimed must not be connected to anything currently going on in the program unreachable. While it is possible for our coding to keep things from being reclaimed, even though we're no longer using them. This is called a memory leak. Memory leaks are parts of memory that the application needed and used in the past and is not needed anymore, but it's storage is yet not returned to the memory pool. Even though garbage collection is handled for us. As we've seen, we still need to be cautious of memory management. Memory leaks can cause JavaScript programs to fail by using up all of the available memory. Let's look at some common things that can cause memory leaks. So first off, global variables. If you keep creating global variables, they will stick around throughout the execution of the program, even if they're not needed. If these variables are deeply nested objects, a lot of memory can be wasted. Not removing event listeners that are no longer needed. As one example of how this particular thing can happen. You could create a lot of event listeners for a particular page or location. And then when the user moves past that, where those event listeners are long, no longer needed. You as a programmer, don't remove them. They're still there. They're still taking up memory, especially for the objects that are linked to. So something to be aware of. The third item, unclear time intervals. Now, set interval is a good example of this. And if you haven't used set interval, basically what it does is it allows you to execute some code over and over again based upon a set amount of time. Now, let's look at a really quick example of this one. I'm just going to call set interval. And set interval takes as the first parameter a function. This is a callback function. So every time the interval expires, the amount of time we enter it invokes this callback function. So I'm going to set up a function here. And then the second parameter is the amount of time in milliseconds that each interval happens. So every 200 milliseconds, this function is going to be invoked, Okay? Now, where this can become a problem, say inside of here, we reference the number of objects. Those objects are, are being referenced there. Sometimes it's kind of thing is done with animation or something like that. But if this is never cleared, if this set interval is not cleared, obviously these references are still going to be valid. And so it will never be able to free up that memory even if it's no longer being used. So a better approach to the set interval problem is declaring an ID and we set that equal to setInterval that will place an ID inside of here. Then when we are done, we should make sure that we're clear interval with that ID, something like that. Okay, one more thing we need to mention, and that's removed DOM elements. If in your program you remove elements from the DOM. But these elements are still reference, such as with an event listener. We talked about that earlier, or in some other way, the memory will not be freed up. Something else to be aware of. Now, we will revisit some of these and other places in the course so that you have a reminder of best practices to prevent memory leaks. All of these things we've talked about can add up and the memory leaks will continue to take more and more memory. If your program runs long enough, it could eventually fail for lack of memory. Even if it doesn't fell, you should make sure to avoid memory leaks and not just rely on garbage collection to save the day. Alright, let's move on to the next topic. 6. Removing Event Listeners to Help with Garbage Collection: In this second topic on garbage collection, I want to expand on some of the techniques which are specific to browsers mentioned in the previous topic. Specifically, I'm going to address how to remove event listeners and JavaScript. Not all JavaScript developers are familiar with this feature, but it is critical when talking about garbage collection. So I wanted to insert it here. Now, if you are coding for the browser, then you'll be working with the dawn. The DOM is short for Document Object Model. It is simply an interface that allows JavaScript to manipulate the content, structure and style of the HTML document. The HTML document is represented using nodes and objects so that the programmer can interface and work with every element on the HTML page. There are numerous commands for working with the DOM. I cover these in detail in my Getting Started course and I've included some of these topics in the appendix. If you need to review. I've included information on the DOM and commands for selecting and working with DOM elements. Alright, now back to the topic at hand. If you have attached an event listener to an object or a DOM element, and that event will no longer be used. It is a good practice to remove the listener. So let's take a look at example. Let's take a look at the HTML code for this page, which I'm currently showing. Here it is, as you can see, it's a pretty simple HTML page. We have a title in the heading, we have some CSS. Then in the body here we have a few div tags. And what I want to do is I want to attach an event listener to this div tag here that has an ID of title. So if we take a look at our JavaScript code, as you can see, this app.js is attached to this HTML file. We have declared a few variables here. Now, I'm just doing this simplistically to show an example here. So I have used some global variables because it's so simple. I don't, I'm not taking the time to do it a different way. I just want to show this example. So we have some global variables here. One is account and one is a title variable that stores that div that has an ID of title. That's how I select it there. So we're going to add an event listener to that. So I come down here and I simply do take that variable there, add event listener. And we need to indicate which event it is. It's a click event as one we want to use. And now what function is going to call That's title? Click this function here. Now at times you may add event listeners with anonymous functions, where you declare the function right here, instead of declaring it before you declare it inside of the add event listener. And that's fine. But you need to be aware that if you do that, you're not able to remove the event listener is a case where you may need to remove it, then you should do it this way. Alright. I'll talk about the reason for that in just a minute when we get to that point. But first, let's just make sure this is working. I'm going to save that. I already have the virtual server running on that page. So I'm just going to resize this. And let's show the console so we can see the console log message when I click on the title. And as we can see that showing up and the counter is incrementing and telling so many times it's been clicked. Alright, so pretty simple. We've added the EventListener there. Now let's look at how we would remove that event listener. So let's say up here, we wanted to remove it once the count was greater than five. So we're just gonna do it quick. If statement. If the count is greater than five. Well that's a situation where we're going to remove the event listener. And here's the command. We have to use the same object that the event listener is attached to. In this case, it's a DOM element. So tidal dot and then the command is remove event, listener, like that. Now this part inside the parentheses here has to match what we had down here when we set up the EventListener. And that's why I say that when you'd use anonymous function, you can't get that to work. You need to declare the function beforehand. So these things are the same. And even if you declare options or use capture, anything else, when you set up the addEventListener, you need to include them up here as well in order to remove them. That's one of the requirements of this remove event listener command. Alright, so let's go ahead and save that. That'll refresh the page. You can see those messages disappeared. Now if we start clicking it, counts, counts, we'll get six. Now it should be removed. Now I'm clicking on it and nothing is happening. That event listener was removed. So that's basically the process of removing an event listener. Wanted to cover it here because we were talking about garbage collection. Alright, let's move on. 7. Understanding the Event Loop: Now before we finish up talking about the JavaScript engine, we need to talk about the event loop. Up to this point, we have established that JavaScript is single threaded. It only has one call stack. It can only do one thing at a time, so it is synchronous. However, JavaScript allows us to do asynchronous coding. A simple example of that is adding a button to an HTML page. We can be running some JavaScript. The user will click the button and we can respond to that click. Because we have JavaScript running doing something else. It doesn't block the user from clicking that button. That would of course, be a horrible experience on a browser. Another example is if we are trying to fetch some data from a database, we make that call to the database and then we can do something else while we're waiting for the data to return. We don't have to sit and wait for that data before we do something else. And that would block other JavaScript processing. We can do something else. And then when the data returns, we can act on that data. We can achieve this asynchronous coding in JavaScript because of the event loop. In the previous scenario, the setTimeout command was handled by the Web API. And I mentioned At that point, the JavaScript engine forgets all about it. Well, once that timing event is done, once the web API finishes at timing event, how does that get integrated back into the call stack so that the task we want completed gets done. For example, if you remember, we have a callback function as a part of the setTimeout. How does that call back function gives back to the JavaScript engine. Let's walk through that previous scenario again, but this time we will include the event loop. Once again. Here's our code, here's our setTimeout. And notice we have a function here. All the function has within it as a console log statement, that's all. The milliseconds are set to 0, so the timer should expire immediately. But let's see what happens. We've gotten to the point where the hello-world function is invoked. So let's continue to walk through that. So we have the invocation of the hello-world function that is added to the call stack. And then it begins working through the commands inside that function. And so the first command we encounter is a console log statement and it's going to log variable a to the console. And so that's added to the call stack. It takes care of that log statement. We see hello on the console. And then the console log command is removed from the call stack. And then we move along in that function, we encounter the setTimeout. Now, the JavaScript engine knows that setTimeout is handled by the web API, so it is sent over there to be dealt with. So the web API sets up a timer. It has the ability to run a timer. And that timer expires immediately because we haven't set to 0 milliseconds. And so when the timer expires, what does it do with that callback function? That's the thing that timer is supposed to do. And so what it does is it adds the callback function to the message queue. Now that callback function will sit in the message queue and it's at this point the event loop comes into play. The event loop will continue to cycle. It will be checking the call stack and see if it's empty. Right now. It's still working on the hello-world function. So it is not empty, but at cycles and continues to look scene. If it's empty. If it's empty, it would then add the next item available in the message queue into the call stack. But right now it's not empty, so we need to continue with the hello-world function. What's the next thing that comes up? Well, it's another console log statements, so that gets added to the call stack. And we go ahead and complete that console log statement World is printed to the console. And so that console log statement is removed from the call stack. At this point we are finished with the hello-world function that is removed from the call stack as well. So as I mentioned, the event loop is cycling and checking the call stack. So at checks and sees it, it's empty. It then grabs the next item in the message queue and adds it to the call stack. And so we get that anonymous function, that callback function, out of the call stack and it begins to work through what that function needs to do. The only thing in it is a console log statement. It encounters that console log statement and adds that to the call stack. The console log statement is completed. An exclamation point is printed to the console that's removed from the call stack. That is the end of that function, and that function is removed from the call stack as well. And so at this point in the call stack is empty, there's nothing left to add from the message queue. And so we're simply waiting for a number, another JavaScript command that needs to be executed. Alright, now before we're done, let me just highlight some important points from this discussion. First, other parts of the JavaScript environment can handle certain tasks. For example, those tasks that belong to the browser. The JavaScript engine doesn't have to process those. We, in this example use the web API to handle that setTimeout command. But the callbacks that are a part of what is handled there are integrated back into the engine using the event loop. It pulls them from the message queue and adds them to the call stack. We achieve Asynchronous JavaScript this way. The event loop is critical in making that happen. Another important point, once a callback is added to the call stack, the code is handled by the call stack as it normally would be if the JavaScript code had not come from the Q, doesn't matter. It's going to process that JavaScript in the same way. Next, a reminder, the event loop is constantly checking for items in the queue. And if the call stack is empty, if the call stack is empty and there is something in the queue, it will add the next available item from the queue into the call stack. And as mentioned, the call stack is one thread, so it is synchronous. It can only do one thing at a time, but its interaction with the event loop and the web API allows the asynchronous coding that we can achieve in JavaScript. Alright, let's move on to the next topic. 8. The Node Runtime Environment: Since NodeJS is such a widely used implementation of JavaScript, I think it is important to briefly look at its runtime environment, especially in relation to the event loop and message queue that we just talked about. This article here cover some of the ins and outs of the Node.JS environment. And here is the URL to this article. You can read it yourself if you'd like. But I wanted to take a moment and look at the diagram it provides of the runtime environment. So if we scroll down here a bit, right here, the node JS Runtime. Now, some of these things you're going to recognize, for example, V8, here's the V8 engine and it is handling the JavaScript. That's what it does. Notice the event queue, different name but similar to the message queue. The event loop is also a part of this. In order to handle things in the event queue. This part here live, you could be thought as similar to the Web API is going to handle things that NodeJS needs to do. That is not done by JavaScript, is done by the environment outside of it. So the V8 engine is still single threaded, still has one call stack, but it can take advantage of other things. And running on a server, there are a number of different things that need to be done and that's going to be handled here. Now know GIS does have some commands that are similar to what we see in the browser. For example, setTimeout, set interval, both of those are available and NodeJS as well, they're not handled by the V8 engine, just like they're not in a browser. They're handled over here. And so there are some similarities. But because it is a different environment, because the runtime is different. It was handled in different ways, but the concepts are transferable. So once again, you can read more about this in this article if you choose to. But I did want to make the point of the event loop and similarities between NodeJS and the runtime environment handled in a browser. Alright, let's move on to the next topic. 9. Exercise Start: Exploring Call Stack and Event Loop: So I wanted to make a little fun exercise as a part of this section, a chance to explore the call stack a bit and the event loop. Now, with all my courses, I always have exercises throughout them because I think it's important for you to actually do things in order to learn that doing of things needs to be on your own at times. And so that's where the exercises come in. The way I do those is I have an initial video introducing the exercise. And then you go ahead and try it. And then when you're ready, you go to the next topic. And we go through that exercise. That's generally the structure. Sometimes they do things a little bit different, but that's generally the structure. So let's go ahead and take a look at what I'd like you to do for this exercise. Alright, the files for the exercise, and specifically the JavaScript file App.js. I've got some code here and let me just explain it really quick and then I'll indicate what I'd like you to do. So right here we're creating an array, and we're creating an array with 10 thousand elements. The number I've used in the constructor, the array constructor right there. And then we use the fill method of arrays to fill that in with ones. And so basically it creates an array with a length of 10 thousand that has ones in all of them. That's what we're doing here. Then I have a little function, I call it pop it. Basically all it does is just pop off a value each time the function is called from this array here. And then we invoke it. And notice we have recursion here because it checks the length of the array. If the length is still greater than 0, meaning there are still items on that array, then it will call itself again, which will cause it to pop off another item. That's recursion we're doing. And as you remember when we did recursion before, we're able to overflow the stack. And so what I'd like you to do is see what number is required to cause a stack overflow. If 10 thousand works for you, then great. But it may not. And so just play with that number of bids, kinda fun just to see what's going to cause that to overflow. And then the second part of the exercise, once you get that stack overflowing, how can you change this? How can you cause this to use the event loop so that the stack doesn't overflow. So kind of an interesting idea, taking advantage of something that's available on the runtime environment so that we don't overflow the stack, but we still can use that same number that was overflowing the stack. So give, give that a try. Obviously, I haven't taught specific commands for you to do this, although you've seen some examples as we've been looking through different concepts in this section. But give that a try with what you know. And then when you're ready, go to the next topic and we'll go through it. 10. Exercise End: Exploring Call Stack and Event Loop: Alright, let's take a look at this fun little exercise here. So right now, 10 thousand, that's how many is in this array. Let's see if this causes a StackOverflow. So I'm gonna go ahead and serve this up and see what we get. So I'm going to jump to the HTML file and then click Go Live. And then jumped to the console. Right now we're not seeing any errors for StackOverflow. So that seems to be working okay. So jumping back to Visual Studio Code, I'm just going to reduce the size of this a little bit so we can go ahead and see the console log while we play with this. So let's go up to, let's go 10,500. Let's see what happens there. So I'm going to change that number there, save it still. Okay. Let's go to 11 thousand. I'm going to save it. And I'm still not getting any problems. So maybe we need to jump up more. Let's go 13 thousand still. Okay, Let's go 15 thousand. And there we get an overflow. So I don't know what the exact number is, but that wasn't really what I want to accomplish here. I just wanted to give you a chance to play with this stack overflow and see that eventually at some point, it will cause the stack size to be exceeded. Then we get the air uncaught range here. Alright, so there's the air we're looking for. Now. How can we change this? So we can still keep this number and still be able to run this recursively and pop off all these items from the array. Well, in order to take advantage of the event loop, we can use the web API, we can use setTimeout to actually invoke this function again. Okay? So instead of calling it recursive, recursively right away, we can use setTimeout to invoke it. And so the way we would do that, setTimeout, and then we pass in the function. Now we don't include the parentheses at this point because that will cause it to invoke right away. We just pass in the function and then it will invoke it once the timer has expired. So we're gonna put a 0 after that for 0 milliseconds we want to invoke right away. And so here's our new setup. Let's go ahead and save that and see what happens down here. Notice we're not getting the air. Let's go ahead and take a look at the array, see how many are left. We're down to 13,600. So that's how many has popped off. So obviously, since we're using the event loop, we're using the Web API with setTimeout. In order to pop these off. It's taking longer to remove all of them because it has to set up that timer. Then it puts something in a queue. And then that item from the queue is then placed in the call stack and then it's popped off. And it's doing that over and over again. So let's look at it against him and we've reduced it to oh, we've got down 67 thousand or 6700 now. So it's moving through them, but it's kinda neat. You can see it do this because it's doing it so much slower. But notice it's not blocking. I can enter stuff here on the console and I'm not blocked from doing other stuff in JavaScript. So that's the advantage of the event loop working for us there. Take one more look, almost done. And by the time I press Return, it was done. So it's now cleaned off that array. So just a fun little exercise to explore the call stack, an event loop a little bit. Alright, let's move on to the next topic. 11. How JavaScript Evolves: As the JavaScript developer, it is important to understand how JavaScript evolves and changes. Because that is something that is definite in the JavaScript world. It is constantly evolving. When I first started using JavaScript many years ago, it was nothing like the language we have today. It almost feels like a different language altogether. We can do so much more with it now. To understand how JavaScript evolves, we need to talk about two things, ekman script and TC 39. First, let's talk about ECMO script. Now. What is a script? I'm sure you've heard of it. It's battered around all the time, basically as simply a specification used by certain languages. It's standardized by the ACM International, and that is where the name comes from. Javascript is the most widely used implementation back my script. So that's why it's entangled with JavaScript so closely. But there are other languages you've probably heard of. The fall of this Ekman scripts standard. For example, Action Script, which is the language behind flash that is based on the Ekman script standard and J script which was done by Microsoft. That's also based on that specification. Now, the first edition of the Ekman scripts standard came about in June of 1997, and that was referred to as Ekman script one or ES1. And since that time, each additional release has been that number has been incremented. So ES x1, x2, x3, and so on. Now, when acme script sixth was released, they started designating the lease with the year. And so at that time, the release was technically referred to as Ackman script 2015 because that's the year that Ekman scripts six was released. However, ES6 has just stuck. And so people refer to that as ES6 or ECMO script 2015. They go back-and-forth between that, because the ES6 releases stuck. That particular release was a huge release with a number of features for JavaScript. If you were in the JavaScript world at that time, you will remember how many things were added to JavaScript. A lot of things that now make regular use of were added during that particular release. Now, since that version of the standard came out, there has been a new release each year. And so we've had Ekman script, 2016201718192020. Every year, a new release has come out. A lot of that comes from the fact that the Ekman scripts six release was so huge. They didn't want another release that big again. And so they're approaching the release is in a much more manageable way. Now, who determines what is in each release? Where does that all come from? Well, that has to do with TC3 nine. So let's talk about that. Now. Tc 39 stands for technical committee 39. And they are a committee that evolves JavaScript. And its members are companies such as browser vendors, that sort of thing have a vested interest in JavaScript. The committee meets regularly and you can follow their minutes online if you choose to. So in that sense, it is transparent. Now in order for a feature to make it to maturity and become a part of a future Ekman script standard release, that feature must go through several stages and we call these stages of maturity. So TC3 dynein, the committee, manages these proposals through these stages until they are accepted as part of the standard. So I want to talk about those stages really quick. So stage one or stage 0, the first stage. But stage 0 is actually submission stage. And this is just a submission of a new feature, a proposal for a new feature. And this must come from a TC 39 member or someone who is considered a TC 39 contributor. And basically it's a document describing what the feature is that they want. That stage 0. Stage one is the proposal stage. Now this is a formal proposal for the feature. And this must have a champion that as a part of that committee, someone who wants this feature to be adopted. So that is stage one. Stage two is the draft stage. And this is really the first version of what will be in the specification for that particular feature. Once something gets to stage to its eventual inclusion is much more likely. Now stage three is the candidate stage. At this point, the proposal is mostly finished and needs feedback from implementations and from users. And then finally, stage four is the finished stage. At this point, it's ready to be included in the specification and most likely will be included in the next upcoming specification. But that's not necessarily a guarantee. Through all these stages, these features are still considered proposals and are not features until they are officially included in the standard. Now, knowing these stages can be important. For example, if you go to a site such as this, and access upcoming features, which is done with this next button to find out what is supporting and what isn't supporting. Notice how it's broken into the stages we just talked about. Here's the candidate stage, here's what's coming up as a possibility in the next Ekman script release. And you can see that some browsers and some compilers are already starting to support these proposed features. You can see that over here, as you move down the stages draft two, you see that fewer and fewer implementations have already been done. And so since these vendors Have a seat on the committee, they know what's coming up. They may be the champion of a particular proposal, who knows, but they begin implementing some of these things prior to them becoming a part of the official specification. You can see we can even go clear down to stage 0, not much going on there at all. So when articles or sites like this are talking about proposals, Ekman script proposals, they're talking about things that are in one of these stages that have not been officially adopted into the standard yet, but are moving in that direction. So that is the process tc threonine follows in order to update Ackman script standard for JavaScript. Alright, let's move on to the next topic.