Advanced JavaScript Concepts | Andrei Neagoie | Skillshare
Play Speed
  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x
73 Lessons (7h 31m)
    • 1. Advanced JavaScript Concepts

    • 2. 01 Introduction1 mio

    • 3. 02 Javascript Engine mio

    • 4. 03 Exercise Javascript Engine mio1

    • 5. 04 inside the engine mio

    • 6. 05 Exercise JS engine for all mio

    • 7. 06 Iterpreter vs Compiler mio

    • 8. 07 V8 Engine mio

    • 9. 08 Other languages mio

    • 10. 09 Optimizing for Compiler mio

    • 11. 10 Exercise Web Assembly mio

    • 12. 11 Call stack and Memory Heap mio1

    • 13. 12 Stack Overflow mio

    • 14. 13 Garbage Collection mio

    • 15. 14 Memory Leaks

    • 16. 15 Single Threaded mio

    • 17. 16 Exercise Problems with single threaded mio

    • 18. 17 Javascript Runtime mio

    • 19. 18 Nodejs mio

    • 20. 19 Conclusion mio

    • 21. 01 Introduction2 mio

    • 22. 02 Execution Context mio

    • 23. 03 Lexical Environment mio

    • 24. 04 Hoisting mio

    • 25. 05 Hoisting Exercise 1 mio

    • 26. 06 Hoisting Exercise 2 mio

    • 27. 07 Function Invocation mio

    • 28. 08 arguments mio

    • 29. 09 Variable Environment

    • 30. 10 Scope Chain mio

    • 31. 11 [[scopes]] mio

    • 32. 12 Exercise Weird scope mio1

    • 33. 13 function scope vs block scope mio

    • 34. 14 Exercise Block Scope mio

    • 35. 15 Global Variables mio

    • 36. 16 IIFE mio

    • 37. 17 this mio

    • 38. 18 this part 2 mio

    • 39. 19 call() apply() bind() mio

    • 40. 20 bind() and currying mio

    • 41. 21 exercise this mio

    • 42. 22 Context vs Scope mio

    • 43. 23 Conclusion mio

    • 44. 01 Introduction3 mio

    • 45. 02 Primitive Types mio

    • 46. 03 Arrays

    • 47. 04 Pass By Reference vs Pass by Value mio

    • 48. 05 Type Coersion mio

    • 49. 01 Introduction4 mio

    • 50. 02 Functions are Objects mio

    • 51. 03 First Class Citizens mio

    • 52. 04 Extra bits of Function

    • 53. 05 HOF mio

    • 54. 06 Exercise HOF mio

    • 55. 07 Closures mio

    • 56. 08 Exercises Closures mio

    • 57. 09 Closures Benefit1 mio

    • 58. 10 Closures Benefit2 mio

    • 59. 11 Exercise 2Closures mio

    • 60. 12 Exercise 3Closures mio

    • 61. 13 Exercise 4Closures mio

    • 62. 14 Exercise 5Closures mio

    • 63. 15 Closures Conclusion mio

    • 64. 16 Prototypal Inheritance mio

    • 65. 17 Prototypal Inheritance 2 mio

    • 66. 18 Prototypal Inheritance 3 mio

    • 67. 19 Prototypal Inheritance 4 mio

    • 68. 20 Prototypal Inheritance 5 mio

    • 69. 21 Prototypal Inheritance 6 mio

    • 70. 22 Exercise Prototypal Inheritance mio

    • 71. 23 Solution Prototypal Inheritance mio

    • 72. 24 Conclusion mio

    • 73. Where to go from here?

28 students are watching this class
  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

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.





About This Class

This course is unlike any JavaScript course you will find online. After many years of working with the language, Andrei has taken decades of experience, combining best practices from some of the top developers in the world, to get you to become one of the top performing Javascript developers. You will go from understanding the basics of JavaScript, to learning it to the point that you can teach it to others, impress coworkers, and wow future employers. You will be in the top 10% of JavaScript Programmers by the end of this course.

Watch a preview here:

This course is the accumulation of years in the field, and combining the best resources, tools, and tutorials out there to create the ultimate JavaScript course that will teach you everything you need to know to be considered a Senior Javascript Developer.

Instead of spending years learning advanced Javascript concepts, you can fast track and get the knowledge that senior javascript developers have in just 30 days.

With this course you are going to learn beyond just the basics like most online courses. You won't just learn patterns, techniques and best practices. You are going to understand the "why" of the toughest part of the language, to the point that when you get asked any question about Javascript in an interview or in a meeting, you will be able to explain concepts that would truly make people see that you are a senior javascript programmer.

Most importantly, you will become a top 10% javascript developer by going beyond the superficial basics that a lot of courses cover. We are going to dive deep and come out the other end a confident advanced javascript developer. I guarantee it. Whether you are a web developer, a React, Angular, Vue.js developer (frontend developer), or a Node.js backend developer, you will benefit from this course because Javascript is at the core of these professions.

Some of the topics covered in this course are:

  • Javascript Engine

  • Javascript Runtime

  • Interpreter, Compiler, JIT Compiler

  • Writing Optimized Code

  • Call Stack + Memory Heap

  • Stack Overflow + Memory Leaks

  • Garbage Collection

  • Node.js

  • ES6, ES7, ES8, ES9, ES10 features

  • Single Threaded Model

  • Execution Context

  • Lexical Environment

  • Scope Chain

  • Hoisting

  • Function Invocation

  • Function Scope vs Block Scope

  • Dynamic vs Lexical Scope

  • this - call(), apply(), bind()

  • IIFEs

  • Context vs Scope

  • Static vs Dynamically Typed

  • Primitive Types

  • Pass by Reference vs Pass by Value

  • Type Coercion

  • Arrays, Functions, Objects

  • Closures

  • Prototypal Inheritance

  • Class Inheritance

  • Memoization

  • Higher Order Functions

  • Functions vs Objects

  • Scheme + Java in JavaScript

  • OOP (Object Oriented Programming)

  • Private vs Public properties

  • Functional Programming

  • Immutability

  • Imperative vs Declarative code

  • Composition vs Inheritance

  • Currying

  • Partial Application

  • Pure Functions

  • Referential Transparency

  • Compose

  • Pipe

  • Error Handling

  • Asynchronous JavaScript

  • Callbacks, Promises, Async/Await

  • Event Loop + Callback Queue

  • Task Queue + Microtask Queue

  • Concurrency + Parallelism

  • Modules in Javascript

The topics you will learn in this course are timeless and will allow you to stay current with any new library or framework that comes out in the javascript ecosystem since you will have the core concepts understood.

I guarantee you that you will not find a course as detailed and as well explained as this one at the end of the course I guarantee you that you will be in the top 10% of JavaScript developers or your money back! And remember,

See you inside the course!

Meet Your Teacher

Teacher Profile Image

Andrei Neagoie

Senior Software Developer + Instructor


Andrei has been working as a senior software developer in Silicon Valley and Toronto for many years. He is now taking all that he has learned to teach others programming skills in order to discover the amazing career opportunities that being a developer allows in life. 

Having been self-taught, he understands that there is an overwhelming number of online courses, tutorials and books that are overly verbose and inadequate at teaching proper skills. Most people feel paralyzed and don't know where to start when learning a complex subject matter, or even worse, most people don't have $20,000 to spend on a coding bootcamp. Programming skills should be affordable and open to all. An education material should teach real-l... See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Your creative journey starts here.

  • Unlimited access to every class
  • Supportive online creative community
  • Learn offline with Skillshare’s app

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.



1. Advanced JavaScript Concepts: Welcome to advanced JavaScript. Constance. The course that will level you up to be in the top 10% off. JavaScript Developers both statement I know my name is Andre, a senior software developer that has consulted him. Worked for some of the biggest tech firms, both in Toronto and Silicon Valley. Azan, Educator. Over 70,000 programmers have taken my courses last year alone. This course has been years in the making. I took all my experience teaching modern JavaScript practices to companies and working on large scale JavaScript projects and put all that knowledge into this course. But this is about you. You can learn JavaScript for free. You can find great tutorials online and YouTube videos. However, what most courses miss out on is the stuff that takes years to learn how JavaScript works underneath the hood, how to write clean, beautiful coat and how to make decisions that senior developers make. After finishing this course, you will be able to explain things to your team. Programmer, friends and boss. You will be confident in your knowledge and go beyond what you get taught from a normal course. These are the things that nobody teaches you and you have to learn by working in the industry for years and years. I'm going to take every mistake I have made things I have learned over the years, combining it with knowledge from other great programmers to fast track your progress. So who is this course for? If you are new to JavaScript but want to learn it in depth as quickly as possible, or you don't feel confident with the language, this course is for you. Or maybe you're a boot camp graduates who needs a deeper understanding off JavaScript or an experienced programmer who wants to learn JavaScript without wasting the time with fundamentals of programming. Then this course is for you to anyone with a little JavaScript. Knowledge will be able to benefit from the course, as I have included bonus lectures on beginner topics as well. So you are able to learn, no matter what your love. Have you ever thought my code works, but I can't really explain how it works. Maybe you're coding in a JavaScript library like react view, Js or even angular. Most developers learn topics on the surface level, but they don't learn topics deeply when a new shiny JavaScript library comes along way, have to relearn everything all over again. Here's the secret. Best programmers know that it's the fundamentals that allow you to continue being a top performer, not learning the newest trends. After taking this course, you'll be able to go back and re learn all these libraries that you thought you understood . But now properly over 1/3 of all developer jobs require some job script knowledge and is one of the best investments you can make for your career. Remember, the things you do to learn and invested should be knowledge that is cumulative so that the knowledge builds on itself. Instead of learning something that might become irrelevant tomorrow, choose things that will make you smarter in 10 years. This course is your answer. As a matter of fact, at the end of the course, if you don't feel like you learn beyond what other courses teach, I have a 30 day money back guarantee, no questions asked. Have a look of the course outline and next video to see if this course is right for you. I'll see you inside 2. 01 Introduction1 mio: Hello. We're starting an advanced course with how Javascript works. But I already know how JavaScript works. I write JavaScript every day. Stop wasting my time, Andre. I know you like to give me a hard time, but let me ask you this. When you write code on a file, do you know what happens? How does the browser read this file? How is Javascript executed? How does know J s work? We write code in a text editor. And somehow this code magically turns into ones and zeros to tell the computer to do something in this section. And to begin this course, I want to build what I think is the most important foundation of learning any language. If somebody asked you Hey, can you explain how javascript works? As if I was five? You're going to be able to answer it by the end of this section, knowing something deeply is being able to understand it so well that you can explain it to anybody, even somebody without technical knowledge. More importantly, you will have an understanding off the language at a deeper level than most people in the industry, so that you can write better coat Let's have a look at what we're going to talk about. In the first part. We're going to talk about the JavaScript engine. JavaScript Braun, time about interpreters, compilers and jit compilers. We're gonna learn about writing optimized code. We're going to talk about coal stacks, memory heaps and some of the things that we have to be careful when it comes to stacks and heaps and that is stack overflow and memory leaks. We're gonna talk a little bit about garbage collection, about no Js and how it fits into this whole javascript ecosystem and its single threaded model. And using what we learn in this section, we're gonna be able to use these fundamentals as we learn higher and higher level concepts has removed throughout the course. So hang in there. Even if you have a good understanding of how JavaScript works, you may learn a thing or two. We're also going to have a little bit of coding, but most exercises in this section are going to be thought experiments and a lot more code is gonna come up in future sections. So hang in there and I hope you are as excited as I am to start the course. It's gonna be a lot of fun. Let's get started. Shall we see you in the next one? 3. 02 Javascript Engine mio: almost everyone that has worked with JavaScript has heard of the V eight engine, the idea of the JavaScript engine. And most people know that JavaScript is a single threaded language that it uses a call back You. You may also hear phrases like JavaScript is an interpreted language. Let's tackle what that means over the next couple of videos. What is this engine that we speak up? Well, if I write some code like, let's say Constant is happy equals two True Well, we just wrote some job script I'm assigning. The true bullion to the variable is happy. Now, how do we read this? Or how does the computer read this? Imagine if somebody comes up to you and gives you a computer and they tell you Hey, tell this computer to display a picture of horses on the screen and you start looking at this computer and you tell the computer to display an image of a horse or horses in French . Is the computer going to understand you? No. The computer would have no idea what you just said in similar fashion. If I gave a computer with a CPU, a file that is a JavaScript file and I tell it, Hey, read this fall and do something for me. Well, the computer only understands ones and zeros at the end of the day. And when we give it the JavaScript file, it's like me talking to a computer in French and the computer being like, Ah, what? What are you talking about? Plus talking to a computer in French while people are gonna look at you like you're crazy person. So the computer doesn't really know what JAVASCRIPT is. So how were we able to communicate using a JavaScript fall so that the computer displays pictures of horses? And this is the first step in our learning? And that is the JavaScript engine. By having a JavaScript engine right over here, it allows you to give this machine the Java script file, and this machine is going to understand this file and tell the computer what to do to display pictures of horses. In a sense, you just created a translator so you can communicate with somebody that doesn't know your language. And this special engine called the JavaScript engine understands JavaScript. Our computer finally understands us because of this JavaScript engine, and it says I'm on it, boss. I'll start displaying those horse pictures. There you go. That's our first step. And over the next couple of videos, we're gonna talk about exactly what's happening inside. But do you think there's one JavaScript engine or many JavaScript engines? Well, as you can see from this Wikipedia list, there are eight Han of engines and they're called Xmas script engines, and we'll get into why that is later. But these air all the JavaScript engines, some of them you may have heard of, like V eight or spider, monkey or chakra. So any time we use an engine were able to give it a JavaScript file. And this Java script file gets understood by the engine, and it allows this engine to communicate and tell the machine the computer to do what we ask it to do with JavaScript. Now these engines are written by programmers. For example, V eight engine is written in C plus plus, but why do people write these engines? 2000 and eight marked a really pivotal moment in history when it comes to JavaScript, because V eight was released by Google before then, most browsers used engines that were very basic, which meant that JavaScript was a little bit slow. Do you see Google had this problem? They have something called Google Maps and Google Maps, as you know, requires a lot off power. It does a lot of things you can asking for directions to zoom in. And Zuma maybe even use Street View and all the previous engines before it would make Google maps very, very slow on the browser and Google because they're a search engine. They want everybody to use their search engine, and they built a browser in order for them to control more of the market. So with Google Maps and their own chrome browser, they said, We're going to write our own JavaScript engine, the V eight engine, so that JavaScript runs way faster on the browser. Then it's done previously, and in 2008 they released V eight. But the big take away for us here is that really, really smart People work on these engines so that our JavaScript runs us fastest possible on the browser, on the server or any type of computer. So every day Javascript gets faster and faster for us because of the work that goes into these engines. OK, but what is inside this engine? This magical machine that understands JavaScript. It reads our code, and then it runs this code. Let's get into that in the upcoming video. But why? 4. 03 Exercise Javascript Engine mio1: Here's a fun little question. Who do you think created the very first JavaScript engine? Just pause and think about this. Give up. Well, The first person to create the very first JavaScript engine was its creator, Brendan Eich, this man right over here while working at Netscape, which became the first commercially available browser, he created the early version of what became to be known as Spider Monkey, which is what far Fox still uses right now as they're JavaScript engine. And Brendan Eich was the very first person who created the language. JavaScript to implement this engine so that you're able to run JavaScript on a browser that previously could on Leigh read HTML and CSS Fun Little fact for you. All right, let's get back to the videos. 5. 04 inside the engine mio: welcome back. So we know that this thing called the JavaScript engine takes are written JavaScript code and does some magic to tell the computer to do what we want it to do. So what's happening inside of this engine? And here's the tricky part as we know this engine can be built by anybody. Yes, that means you can build your own JavaScript engine, but it's a lot of work, and at the end of the day, it's just a program and the V eight engine, which is the most popular, most common. And some would say the fastest JavaScript engine that the chrome browser and no Js uses, which we'll talk about later on. This engine is written and C plus, plus a low level programming language. But let's see what's actually happening inside here. Inside this engine, it looks something like this. We give it a JavaScript file and first is does something called lexical analysis, which breaks the code into something called tokens to identify their meaning so that we know what the code is trying to do. And these tokens are formed into what we call an A S T. That is an abstract syntax treat. So we parse the code that is. We try and figure out how the text is divided up based on key wards from JavaScript, and it gets formed into this tree like structure called Abstract Syntax Tree. And there's a fun little to online that you can use to demo this. If we go to a SD explorer dot net, I'll show you how this abstract syntax tree looks like and you have a bit off code here, and, as you can see again, look at it in Jason Format or he can use it the tree, and it breaks down the program into different things that are happening. We have a variable declaration, a declarative. And although this may look like gibberish right now to you, this allows the engine to understand what's going on in the program for at least break things down one by one and once ends this form, it goes through something called an interpreter profiler compiler, and we get some sort of code, which we're going to talk about later on, and this whole engine is going to spit out some code that our CPU on our computers is going to understand to give it instructions and you can think of this whole process again, which we're going to talk about in more detail coming up as something like this. We can create our own JavaScript engine by saying function. Let's say Js engine function that takes him son code and this code is going to return for us. It's a code dot split, and we'll use some rejects here just to split up our code. And now if I write some code here, let's say Js engine and we give it our code, which will be a string that says Variable A equals to five. Look at that. We've created a simple engine. I know, I know there's a lot more complexities to it than that, but that's what it's doing. We're giving it a piece of code which just gets string ified, and then it tries them, breaks things down into different parts, so that maybe in this function, we can say if you see variable key word, that means whatever comes after, it is a variable that we're gonna assign and so on and so forth, but you might see a problem here 6. 05 Exercise JS engine for all mio: What problem or problems do you see with everybody creating their own engines and JavaScript just like we did, right? Can we just create our own engine and all of sudden Boom. There it is. We have our javascript engine. Well, yes, you can definitely do that. But remember our list over here, how it was called Acma script engines and not javascript engines. That's because if everybody could just create a JavaScript engine, it will just be total chaos. Which is why Acma script was created. It tells people, Hey, here's the standard and how you should do things in JavaScript and how it should work. And Atmos script is the governing body of javascript that essentially decides how the language should be standardised. So it tells engine creators this is how javascript should work. But internally, how you build the engine is up to you as long as it conforms to the standards. And if we go back to our example over here, this engine inside of this box, as long as it conforms to Acma script standards, I can do whatever I want as an engine creator. So companies and organizations are battling to have the fastest engine, so people use their tool. For example, Google is really interested in having the fastest engine so that more people use their chrome browsers so that they use their search engine so that they can sell more ads and make more revenue. But keep this in mind that this could be implemented anyway. We want, and it constantly changes to find the fastest way possible to have JavaScript work in our browsers or even outside of our brothers. And we're gonna be talking about the V eight engine here because it is the most popular and you might see some different variations off this. But what we're gonna talk about here applies to most JavaScript engines. And although things may change over time, as long as you understand the principles and why it's built the way it is, we're gonna be able to understand how to write optimized coat. But before we get into that, let's talk about what these things are. We have the interpreter and compiler. I'll see you in the next video. Bye bye 7. 06 Iterpreter vs Compiler mio: Welcome back. Let's talk about interpreters and compilers, which, as we can see our important pieces in our JavaScript engine you see in programming there generally, two ways of translating to machine language or something that our computers can understand , and where we're going to talk about here actually applies to most programming. Language is not just a job. Python Java C plus, plus any language you can think off is going to use some of these concepts. So it's very important. Let's start with the 1st 1 The Interpreter with an interpreter. What we do is we translate and read the files line by line on the flight. Let's have a look at how this works. I have a piece of code here that, well, doesn't do very much. Does it have a function that does some calculation? And we just loop over this calculation, which is five plus four right over here, and we do that well 1000 times. That's a long time, and you see that we get the result nine over here. But the loop is happening over and over. So if I go console dot log here, I we see that yet this is looping over and over and over now with an interpreter. If I give this file to an interpreter, the translation happens. Line by line on the fly, and this is how you think the coach should be run, right? The interpreter sees the first line than the second line, then the third line and says, All right, this is a function. And then it goes to the next part and says, All right, I should loop over this a bunch of times and it starts doing some calculation. It's going to go and see. All right, That's what the function is. I'm going to run five plus four and then I'm looping again, so I'm going to go once again. Run some calculation. Five plus four. Some calculation. Five plus four. Any keeps running, keeps running, keeps running. And this is how you might think code should be run right, because interpreting code simply means taking a set of instructions like we have over here and returning an answer and doing something with that coat. It's just like me telling a computer to do this. Then do that. Then do this. And initially that's how Javascript worked. It was interpreting using an interpreter. Which makes sense. All right, But what about a compiler? What's the deal with a compiler? Well, a compiler I, like an interpreter, doesn't translate on the fly. What it does is it works ahead of time to create a translation of what code we've just written, and it compiles down to usually a language that can be understood by our machines. Let's have a look at this in more detail with a compiler This time around, it's going to take one pass through the code and try to understand what the code does. And it's going to take the program in JavaScript or any type of language and write a new program in your new language. Let's say to programming language, why or X in this language that it spits out, Let's go, it just x well, this language that it spits out if we interpret it, this language that is going line by one wanted a time and running it, it's going to create the same results. Eyes are previous language, so compiler tries to understand what we want to do and takes our language and changes it and do something else. And this usually happens into something called a lower level language such as machine coat . Now I know you're still alot but confused. You see, the definition itself is actually a little bit fuzzy. In some respects, all languages have to be interpreted and compiled because it has to run. That has to be interpreted. And it also has to most likely get translated into something low level like machine coat. For example, we have, ah, high level language here, like JavaScript, and we run a piece of code here on interpreter will take this code line by line and spit out byte code like this that will execute this code for us. Or a compiler might take this code and go through this and spit out machine code just like that so that it can give it to a CPU so that the CPU can actually run the coat. But remember how I said a program or most languages are both compiled and interpreted because over here, x 86 code, which is machine code, this is handed off to the CPU, and he needs to interpret these instructions. And in reality, when it comes to X 86 is actually too slow to be interpreted literally. So instead, most modern CP use will compile this X 86 code into its own native micro coat. So, as you can see here, there's a lot of layers that happen on and on. But the main takeaways is this. There are two ways to run JavaScript using an interpreter or a compiler. Now, I know it's still a little bit fuzzy, but if I ask you, why would we want to do one over the other? What are the pros and cons on each? What do you think that is? Why would you pick one over the other in the next video? We're gonna explore that, I'll see you know, but by 8. 07 V8 Engine mio: Welcome back. Let's have a look at the pros and cons of each. First off interpreters are quick to get up and running right, because if we go to our example with an interpreter, we don't have to convert this into another language like language X. Like I showed you with a compiler. There's no compilation step before you can start running your coat. You just give this to an interpreter and the interpreter starts translating their first line and just runs the code for us. Because of this, an interpreter is a natural fit for something like JavaScript, Right? A JavaScript file gets sent from the server to the browser to decline on the front end, and we want that job script to execute right away because our users, they're going to be waiting on the webpage trying to interact with our application. And JavaScript originally was created for the browser, so being able to interpret JavaScript and run it as fast as possible, well, that was ideal, and this is exactly why it JavaScript used in Sir Peter's at the beginning. But there's a con with using an interpreter, and this is the same problem that Google had back in the day when they had Google maps running a lot of JavaScript. But it'll get slower and slower and slower because the problem with interpreters is that when you're running the same code more than once, for example, if you're in a loop like this one over here we're running this piece of code over and over and over, even though it gives us the same result, it can get really, really slow. The compiler actually helps us here. It takes a little bit more time to start up because it has to go through that compilation step of the beginning, go through our code, understand it and spit it out into a another language. But the compiler will be smart enough that when it sees code like this and this is obviously a simplified version of it. But if it sees code like this that we just loop over and it has the same inputs returning the same outputs, well, it can actually just simplify this goat. And instead of calling this function, multiple times can just replace this function with something like nine, because we know that we want to return. Not because a compiler doesn't need to repeat the translation for each passed through. In that loop, the code generated from it is actually faster, and these sort of edits that compilers do are called optimization. So let's go back to that question. Interpreter or compiler? Which one is better? Well, they both have their pros and cons. Compiler obviously takes a little bit longer to get up and running, but the code is going to eventually run faster or interpreter. That is really fast to get up and running, but unfortunately, doesn't do any optimization. Is there a way that we can get the best of both worlds? And this is what some engineers came up with in late 2000. And if we use Google as our example with the V eight engine, what if we combine the best of both worlds? What if, instead of using the compiler and interpreter, we combined these two and create something called a jit compiler or just in time compiler, and this is exactly what browser started doing. Browsers started mixing compilers specifically these jit compilers for just in time compilation to make the engines faster. So let's see how a V eight engine does this underneath the hood in order to use the best of both worlds. Remember, we parse the code, we turn it into an abstract syntax tree. And then this code initially goes to on interpreter. And by the way again, I'm showing you what the V eight engine does their small changes in different engines. But this is probably the best, most optimum way to run the JavaScript engine. As I'm recording this video. Initially, the code gets sent to the interpreter and in the V eight engine. This is called ignition. I know they have really cool sounding names to make them sound like they do thinks fast. But this interpreter in the V eight engine is called Ignition, and it takes this ASD and it spits out by coat. And remember, byte code is code that's not as low level as machine code, but it's code that is able to be interpreted by the JavaScript engine in order to run our programs. So that's the first step. But then we see over here that there's something called a profiler, this old man that's checking out our coat in this profiler, also called a monitor. Monitors and watches are code as it runs. It makes notes on how we can optimize this coat, such as how many times it is being run. What types are used in how we can possibly optimize this and using this profiler as the code is running through our interpreter, which tells our browser what to do if the same lines of code are run a few times. We actually pass off some of this code to the compiler or a jit compiler just in time compiler, because as the code is running, the interpreter is going to say, Hey, here's some quote for you to optimize, passes it off to the compiler and the compiler, as the application is running, takes a code and compiles it or modifies it So it does what you ask it to, but trying to make optimization so it runs faster, and it then replaces the sections where it could be improved off the by code with optimized machine code. So that code that optimized code is used from that point on instead of the slower by code. So it mixes and matches things and it constantly runs through this loop. And this means that the execution speed of job script code will be improving, right? This means that the execution speed off the JavaScript code that we entered into the engine is going to gradually improve, right, because the profile and the compiler are constantly making updates and changes to our by code in order to be as efficient us possible. So interpreter allows us to run the code right away, and the compiler and profiler allows us to optimize this code as we're running. That's where the name comes from. Jit compiler Just in time compiling in this compiler for V eight is called Turbo Fan again , a cool sounding name to make it sound like things are going fast and by the way, just a bit of a fun fact. Previous versions of V eight engine actually used to jit compilers with really cool sounding names, but they changed it to this method because there are some faster optimization is that they could do so. Why did we just learn all of this? You can write JavaScript without knowing any of this stuff, and you'll be fine now that we know how the engine works underneath the hood, we can write more optimized coat code that the compiler can take and run a faster than our regular job script. And we also can use this knowledge to make sure that we don't confuse the compiler because the compiler isn't perfect. It could make mistakes, and it can try to optimize code that actually does the opposite. And if it makes a mistake and it does something unexpected, it does something called the optimization, which takes even longer time to revert it back to the interpreter. So by learning this, we're gonna have a video coming up where we learn how to write, optimize code so that we help out this profiler and compiler to make sure that we're able to run the fastest code possible. And let's learn those optimization. But first, let's talk about something quickly. I'll see in the next video, but 9. 08 Other languages mio: I wanted to do a quick video to see how what we just learned applies to different languages . For example, you might have heard of an executed ble file that is a dot e x c five, especially if you've ever used Windows before you double click a file that ends in dot e X E, and then the code starts running. The application starts running, and that dot e x C is an execute herbal. And most of the time these dot TXT files are created by C plus. Plus, you ride a C plus plus code, and you compile it to a dot e x C five. For example, you can use a command like G Plus, plus your program Gantt C plus plus. So that's your C plus plus file, and you're going to output it to an execute herbal your program. And this is going to create that dot e x e file that you compile down from C plus plus to an execute herbal machine code so that when you double click a file that is your program, it's going to run because it's been compiled. Now when you use a program like let's say, Java. Java, on the other hand, uses something called the JV M or Java virtual machine, where it compiles your crowed or interprets your code to buy code inside of this J. V M. And this Java virtual machine is going to understand the spike coat. So unlike a compiled language that has to be compiled for each specific type of computer, a Java program on Lee needs to be converted to bite goat once. And that by code can be understood by the Java virtual machine. And that's where the term for Java write, once run everywhere, came from. Now. One thing to know here is that by code is not a native machine coat that is. Most computers won't understand the spy code. They might understand machine code, but not by code. So with by code, you need software such as the virtual machine or a JavaScript engine so we can executed directly. I can't double click a byte code file and run it without an engine or a JavaScript machine , so I have a question for you, knowing what you just learned now is JavaScript an interpreted language. You'll hear this a lot. JavaScript is an interpreted language, but learning what you just did is JavaScript an interpreted language. I mean, yes. Initially, when Javascript first came out, you had JavaScript engines, such a spider monkey created by Brendan Eich that interpreted JavaScript to bite code. And that engine was able to run inside of our browsers to tell our computers what to do. But things have evolved. Now we don't have just interpreters. We also use compilers to optimize this coat. So this is a common misconception when somebody says javascript is an interpreted language . Yes, there is some truth to it, but it actually depends on the implementation. You can make an implementation of JavaScript of the JavaScript engine that perhaps Onley compiles. And by the way, this is also true when it comes to something like python python can be run through a compiler, or it can also be interpreted, even interpreted through something like the Java virtual machine. So it all matters, depending on implementation. So the next time somebody tells you Hey, javascript, that's an interpreted language. You can Solon, super smart and nitpicky by saying Well, not technically. Technically, it depends on the implementation. All right, I'll see in the next video, But 10. 09 Optimizing for Compiler mio: welcome back. Why did we just learn all of this? Well, because now we know a critical part in being a JavaScript programmer. We want to write code in a way that helps the compiler make optimization. We don't want to work against it and make things slow throughout the rest of the course. We're going to learn in different ways to write a fishing coat, but I want to give you some basic things to watch out for when working with JavaScript engine. Now keep in mind that most of these things I'm going to show you will seem like things you don't really use or see that much anymore. And that's because most developers don't use them, since they can be bad for optimization. But it never hurts to know what they are. It doesn't mean that you should never use them, but that the use cases for them are very rare. So here's the list. In order to help the JavaScript engine, we want to be really, really careful with these on the left functions that call literally the malfunction which comes with javascript can be very problematic arguments which we're gonna talk about when we get into functions of this course, something that comes with every function. There are many ways that we can use this keyword by JavaScript, but there are many ways that makes compilers on optimize herbal. So we have to be really careful with the using arguments, and I'll show you later on how we can use parameter de structuring to avoid using arguments . Foreign loop, for example, when looping over objects can also be problematic sometimes. So I like to use object Doc Keys and iterating over the object keys. That way, the with statement which once again you don't see very often in the wild anymore, is another problematic one. And also the delete key Word in JavaScript can be problematic. Now I'll leave. Resource is for you to read up on them if you really, really want to get into the wheat. But there's two main things I want to talk about here that are the main reasons that these things in Javascript can make our code less optimized. Let's have a look. The first thing I want to talk about. It's something called in line cashing and in line cashing, weaken demonstrate this way. Let's say we have a function and dysfunction will say find user that takes in the user parameter And this function will just return a template string they found That's a user dot first name, then last name. And here we can just create a knob Jek to call it user data that will have the first name Clay Johnson and last name SE Jr. Now all we do here is say, find User and give it the user data object now in line cashing Does something really interesting? Do you two in line cashing done by the compiler code that executes the same method repeatedly, That is, let's say, the find user method or function was being called multiple times. Well, the compiler can optimize this so that whenever it's looking for the user data, which has first name and last name, you can use something called in line cashing where, instead of looking up this object every time finding the key, that is first name and last name, and then their values it will cash or in line cash so that find user just becomes this piece of text. So if we call, find user over and over and over, we were just replaced that with found Johnson Junior. Because of the end of the day, that's all that the function is doing. The other one that is really important for optimizing compiler code is something called hidden classes and a lot of the gotchas that I showed you previously. That is this one over here, such as the delete key word really affect this hitting classes when it comes to compilers. Let's have a look. If I had a function, let's call it Animal. Dad receives X and Y parameters, and we'll use the this keyword for now. We're gonna learn more about that soon. And discourse, don't worry. But let's say we just have this animal with X and Y properties, and now we create a new object. Let's say cost object one is going to be a new animal that takes in one and two as the properties doesn't really mean much, but there's our first object and then our second object. We'll do the same thing, but this time with different parameters three and four. Now a compiler is gonna take a look at this and say, All right, we haven't animal that we're creating here, and we're assigning it to object. One an object to. But if I go ahead and add object one dot a to equal, let's say 30 and then object juan dot be to equal ah 100. And I'll do the same thing for the object to, except that this time around for object to. I'm going to create it in a different order. So that is, I add the be property and then the a property to object to. Hopefully, that's not too confusing. That code is actually going to make the compiler run slower or d optimize the coat. And that is something called hidden classes you want to try. And in Stan, she ate your object properties in the same order so that hidden classes, which is what the compiler uses underneath the hood, to say, Oh, this animal class, this object one an object to objects have the same hitting class that is, they have the same properties. But as soon as you start introducing things in different orders, it's going to get confused and say they don't have a shared hit and class. They're two separate things, and internally, that's actually going to slow things down. So one thing you want to do in a situation like this is to assign all properties often object and its constructor over here. So that is to add the A and B property in here so that you avoid this issue or making sure that we add things in the same order. And that's why there's this issue off delete key word as well. If I delete the property here, all of the object well again, I changed a hitting classes so that they don't match up anymore. Now, when it comes to optimizing the compiler, their small little gotchas like that that you don't really have to worry too much about it . The key take away from here is that we should write code that is predictable not only for humans, but also for machines. The more predictable your code is, the better it will be because they'll have no surprises. And throughout the course, we're gonna learn these practices that will help us, right? Optimize code that is predictable. And that doesn't confuse to compile it. I'm not going to mention every single time that we're doing an optimization for the compiler. We're just going to assume that these best practices when incorporated. Like I'm going to show you throughout the course. It's going to help us, right? Fast efficient coat I leave. Resource is for you here. If you want to learn a little bit more about this topic and really get into understanding what this hitting classes, it's It isn't something that you need to worry about too much. But for now, I'll see you in the next video. No, by 11. 10 Exercise Web Assembly mio: Here's another test for you and maybe something that you've been asking yourself throughout these past couple of videos. If we have to do all this interpretation and compiling on the language, why not just use machine code from the beginning? Why don't all programs just use machine code ahead of time? We compile our code, let's say JavaScript and then we just give our websites our machine code so they don't even have to worry about all this compiler interpretation and jit compiler. What do you think the answer to that is? Take a second here, pause the video and see if you can answer this yourself to test your comprehension. All right, You ready for this? You see, if JavaScript working Paul, then either compilation would have to be super fast. Because remember, our JavaScript files get sent from the server to the browser. So the compiling has to happen on the browser or the competing browsers. That is Firefox. Microsoft Edge chrome browsers would have to agree on some binary execute, herbal format or standard that can understand this machine code because of the end of the day. These browsers are the ones that are executing the coat now when JavaScript was created in 1995. That's the start of the browser wars where browsers air competing against each other. So compiling the code ahead of time or even just compiling the goat on the browser was not feasible at all. Because back in the day, that was really, really slow. But also having all the browsers agree on an excusable format to run JavaScript. Well, they didn't get along, so that was going to happen. Even now, browsers have different ways of doing things, and there's just no real standard. But luckily enough, things might change in the future. We now have something called Web assembly and something that you should really keep an eye on because this could be a game changer in the future. We have the standard binary execute herbal format called Web Assembly, and this is what we didn't have in 1995. We didn't have the competing browsers agreeing on this format where we can compiler code all the way down to Web assembly. This execute herbal format so that Iran's really, really fast on the browser instead of having to go through that entire JavaScript engine process so keep an eye on Web assembly. But I hope now, if you've heard about Web assembly and you're curious what it is, that's the big advantage of it. We might not have to do all these interpreter compiler and all the steps that JavaScript requires to actually run the code on the browser. All right, I'll see in the next one double. 12. 11 Call stack and Memory Heap mio1: Welcome back. Up until now, we've talked about topics that are definitely important, but they won't really affect your day to day coating, and you won't get really asked about what we just learned about interpreters and compilers in an interview. But starting in this video, we're going to learn about something that will come up again and again in your career. That's very important and foundational to javascript that any senior developer should know . And it's also something that we're gonna keep bringing up over and over throughout this course, so make sure you pay attention. And up to this point you might have wondered why I ignored completely this little pink and orange box, the call stack and the memory heap and good. You've been paying attention because we're going to talk about this over the next couple of videos. You see, we learned that the JavaScript engine does a lot of work for us, but the biggest thing is actually reading our code and executing it right. And what do you think the two most important things in this step are? That is one we need a place to store and right information that is to store our variables are objects are data of our APS and a place to actually run and keep track of what's happening line by line on our coat. Well, we use call stack and memory heap. For that, we need the memory heap as a place to store and right information. Because of the end of the day, all programs are just read and write operations. That way we have a place to allocate memory, use, memory and release memory that is to remove it, just like these cupboards over here and two with the call stack. We need a place to keep track of where we are in the code. So with that, we can run the code in order. And when thes two things, the JavaScript engine is able to do that, so to review the memory heap is where the memory allocation happens, and the coal SEC is where the engine keeps track of where your code is in its execution. But enough diagrams looks to actually show you an example. When we look at call stack and memory heap. Well, if we write a simple CONST number equals 6 10 What we're seeing here is Please allocate memory for the number variable and make this number variable point two in memory. In our memory. Heap the value 6 10 If we do, let's say a string. It's the same thing we're going to tell the engine to. Hey, please allocate memory for a string variable. So now whenever we use string, we can say Oh, go into our memory Strangest, pointing to somewhere in our memory to this value of some text. Another way to think about it is if we have an object that is going to equal. First name is going to be Andre and last will be my very confusing last name that nobody can pronounce nag way and all we're telling the computer here is saying, allocate memory for an object and its values. So now we're telling the JavaScript engine hate. I'm going to assign this human variable, and this human variable is going to point any time. I call it to a region in memory in our memory heap that has these values their first and Lasky that point to Andre and nag way of values to review our memory. Heap is simply a free store is a large region in memory that the JavaScript engine provides for us, which can be used to store any type of arbitrary data in an on ordered fashion. There's no order to this memory. It just allows us to use variables 2.2 different storage areas just like a little covered here. And a lot of science goes into optimizing the way spaces allocated here. But we don't need to worry about that. We know that the engine takes care for us to put data into storage boxes for us, and that's pretty easy, right? Memory heap is not that hard. Just a place for us to store our information boat about the next one. Costa. How does that help us? Well, if we go back to our code, let's write some code here and we'll create something very simple. We'll have a function that will be called Calculate and this function well have a sum total that does some random calculation like four plus five, and it's going to return sum total. It's going to return nine. So as we know, this function is going to be allocated to memory so that any time we call calculate, it's going to look in memory and see Oh yeah, calculate. I have it right here. Here, run this piece of code. And every time we run this code calculate we use the call stack so we can think of call Stack as a region in memory, which operates in first in last out mode. What does that mean? Well, when we run, calculate we simply on our coal stack. It's going to just add the calculate function on top of the stack. And after we finish running this function, it's going to remove it now to make this a little bit clearer. Let's add another function to here, and then we're actually going to run this in Google Chrome to show you what's happening. We want to create another function called Subtract to Man. It's going to take a number as a parameter and what's going to just return numb minus two. Just going to subtract two so that in our calculate function, we can just return, subtract to and give it the sum total. So it's going to subtract to from nine, so it should give us seven. Now, let's see how the call Stack is going to work when we run this function. I'm going to copy this and go to our Google chrome developer, Consul. Now I'm going to click on sources here, and you might have to click on this arrow to go to snippets. And I can just add a new snippet here, and as you can see here on the right hand side, I have something called coal stack that will show us what's happening. Fight copy and paste this code. Let's see what the call stack does. I'm going to add a d bugger statement in here, which is gonna pause the execution right here before I write, Calculate and let's hit, run and see what happens. All right, we've paused our execution, as you can see here before we've done calculate. So the javascript engine has gone through this piece of code. I see that. OK, we've declared our functions. The JavaScript engine knows what subtract two and calculate is and it has some place in memory that it stored this information, but we haven't run anything yet, But on the coal sack, I see something called anonymous year that we didn't see before. What is that? Well, that's the global execution context, and it's something that we're going to talk about in the next section, but for now, it's anonymous because there's no name for this file. This is the JavaScript engine saying, Hey, I'm running this file. This is the first item on the stack, and the first action that we take is to run this file. If I click on this down arrow, we will see that we get to calculate that's the next step in the JavaScript engine. And if I click it down again, see what happens to call Stack here. The calculate function just got pushed on top of the stack. Charcoal stack now has the anonymous function, which was the global execution context, which was the main run of our file. But now, because we've run a function, were inside of this function. Now, on top of the call stack, we have calculate. If I go next, I see that I've calculated the sum total, and the next line is going to be subtract to see what happens to the call stack here. If I click next, we're now inside of subtract two. Another function was called and we push another item on the stack. Now here's the interesting part we are not done with the calculate function are we were still inside of this calculate function, and because this calculate function called Subtract two were now inside of subtract two. I know kind of confusing, kind of like inception, but that's what's happening here. The call stack tells us. Hey, right now, where are we in the code while were at Subtract two. Once we're done with, subtract two, then we can go back to calculate. And then once we're done with calculate, then we can go back to the global anonymous function, which is what happens in Line 11 here once we finish our work. So watch if I click next. The Subtract two is now going to return NUM minus two and the call stack thesis track to gets popped off the call stack. We're now attack late, and we have some total, which is nine, and we know what subtract two is That is numb minus seven. So if I go next, calculate gets returned, and if I go next, we're done with the function. Look at that. Our answer returned seven, and that's what I call Stack Does the call stack stores, functions and variables as your code executes at each entry state off the stack, also called the Stack frame, which is the frame over here. These three stacks allows us to know where we are in the code, and it runs in a first in last out mode that is, the 1st 1 in is the last one getting popped out and we can keep adding, keep adding to the stack and eventually it pops. Pops pops all the function goals until we are done with our commence. And we use the memory heap to actually point to different variables and objects and data that we store so that we know where to look. And by the way, this is the way it works. In most programming languages, we have call stacks and memory heaps, and these are the two locations that Javascript remembers Haydn's now, since every Javascript engine has different implementations. Where variables are allocated is not 100% the same all the time, so a good way to think about it is this simple. Very bull skin usually be stored on the stack, and we'll learn about this later on and objects complex data structures like objects, arrays, and functions which we're going to talk about are stored in memory heaps. The cool thing about call stacks is that it allows JavaScript to nowhere needs to be in the coat. Whatever is on top of the call Stack is where JavaScript is running. How geniuses that one last thing. If we go back to the function that we had and let's say this time around we're just going to return some total and not going to use, subtract to function at all. Instead, we're going to run calculate twice. What do you think's gonna happen? Well, if I run this code, we have our global execution context. We hit next because a new function was called. We added to the stack on top. There we go. And now we run through this code and we return nine and the call stack cath played. Function gets popped off. We're done with the function, and then we go on to next line, which is line 11. And once again we call this function. As soon as we call a function, it gets popped or pushed onto the stack. It runs through the code and then returns and he gets removed from the step. All right, we've got in that part. Now let's get into a fun video where we try and break this and cause a stack overflow I'll see in the next one, but by 13. 12 Stack Overflow mio: Welcome back. Let's try something fun. What happens if we keep calling functions nested inside of each other over and over and over? We saw in the previous video with the calculate function. If you call calculate Lined 10 than line 11 then lie 13. This stack is going to get pushed on and then popped off, pushed on and then popped off. But what if we have functions that are nested inside of each other so that we keep growing this stack until it gets larger and larger and larger and larger and larger until we can do it anymore? Well, that's called stack overflow, just like the name of a very popular website for developers and programmers and stack overflow can be caused very easily. Let's have a look. All we need to do is create a function. Let's call it inception, and this function well, just called itself. I know that looks confusing, and what we're using here is something called Rikers In and Ryker Shen is a function calling itself. There are some cases where things like this Ryker Zhan is quite useful, but that's something beyond the scope of this course, and it's something I teach in my other courses for data, structures and algorithms. But Rikers in is one of the most common ways to create a stack overflow or a lot of functions nested inside of each other to create that stack that keeps growing and growing and growing. In this case, if I run inception, it's going to keep adding things onto the stack more and more and more. So what do you think happens if I run this? Well, I get a maximum call stack size exceeded. We actually get a stack frame of what the air is at each entry. The state of the stack, also called the Stack free, is shown if at any function produces an heir, though, job script is going to print this stack trace, which is simply a snapshot off code execution at this stack frame. And you see over here that I'm calling Inception, inception, inception, inception, inception. So the same function is being called, and I get an air now back in the day with chrome. It wouldn't give you this. Air and the browser were eventually just crash. But in order to prevent the browser from crashing if it reaches a limit it's going to print out this air saying, Hey, you've just created a stack overflow. How cool is that? All right, so that's one way to cause problem with our coal stack. That is one of two places that are JavaScript engine works. But what about the memory heap? Is there a way to do something like this with the Mary Heap? Well, let's find out in the next video. 14. 13 Garbage Collection mio: Welcome back. Okay, Okay. I may have lied a little bit before we can talk about memory leaks. We have to understand this concept of garbage collection. JavaScript is a garbage collected language. That means when javascript allocates memory, let's say, within a function we create an object, and that object gets stored somewhere in our memory. Heap automatically with javascript. When we finished calling the function. And let's say we don't need that object anymore, it's going to clean it up for us. So JavaScript automatically frees up this memory that we no longer use and, well, collect our garbage just like this. So on Lee, the data that is still useful to us remains so that this way, we make sure we don't use up all the memory we have available because, as we know, memory is limited. How nice is that now, in garbage collected languages like JavaScript, the garbage collector frieze memory on the heap and prevents what we call memory leaks. That is when the memory gets too big, too big until we reach our maximum size. Kind of like we did with stack overflow. But that is hypothetically. There's no perfect system, right, and garbage collection gives us a false sense of security that, oh, we don't have to worry about memory management because this garbage collection is done automatically, and it's smart enough to figure out what we need and what we don't. But again, this is actually a big mistake. It gives JavaScript developers the false impression that they can choose not to care about memory management. And as you'll see, they're ways to actually make mistakes where the garbage collection won't actually free up the memory and you still have little pieces of boxes year that don't have any reference, or don't point to anything really that are still hanging your run. Now, in low level languages like C, you control garbage collection and you tell it to remove parts of the memory. Now that's very, very dangerous. But it's also the reason that programs like see are extremely fast, the memory efficient because you control garbage collection, and with that control, you can make it really, really optimized. So how does garbage collection actually work in? JavaScript? Well uses something called Mark and Sweep algorithm, and this is a great video that shows how it works. Imagine, on the left here are variables that we have in our program, and these very bowls 0.2 different objects. And perhaps an object points to another object and so on and so forth. And as soon as we remove that reference from that object, well, it should get deleted rate. For example, object five we don't need anymore because nothing is linking to it. So if we run this, we mark what we need. We sweep while we don't, and that's how garbage collection works. If we look at this through code, we can simply show that inaction by using human over here in our object. If I all of a sudden and let's change this to a var so we're gonna sign it something else, and we'll say that var or human now equals five. Well, this piece of memory that is my main my name, first name and last name is still in the memory heap, but we don't need it anymore. Nothing is referencing that piece of code. Or perhaps this human variable was just inside this function. And once this function is done executing and it's popped off the stack, well, we don't need that variable anymore. So the garbage collector is going to mark and sweep and clean this from memory. And now that we understand how garbage collector works, we can take advantage of this and show you how memory leaks happen. I'll see you in the next video, but 15. 14 Memory Leaks: Welcome back. Let's create our own memory leak. How can you do this? Well, the easiest way to do it is to just create an array, and we'll say that it's an empty array to start off. But within here, we're going to create a loop. Let's say I equals to five, and I want you to keep looping as long as I is greater than one, and I'm going to say I plus Plus that means let's increment I by one. Now you see here that I'm creating an infinite loop because while I is always going to be bigger than one, so all I have to do here is say, array dot push, and we're going to add to the array I minus one. Now when I run this code, what's going to happen is we're going to run an infinite loop that keeps pushing to the array I minus one over and over and over until, well, we fill up our memory and there's nothing left for us to use. And, well, we're gonna crash the browser. Let's see how this happens once I press enter, all right, things are happening. Oh, did you see that? Something were wrong While displaying this webpage. We just crashed our browser. Go ahead and play with that if you want, or try to create your own memory leaks. But what I did was I filled up our memory heap with MAWR and more and more data. The garbage collection wasn't really working because, well, we had this array. We were using the Saray over and over until we crashed our program. So memory leaks are pieces of memory that the application have used in the past but is not needed any longer, but has not yet being returned back to us to the pool of free memory. Now, this was a silly example, and most likely you're not going to do in your programs. But there are three common memory leaks that happened that I want to show you so you can avoid them in your application the very 1st 1 And this is something that you've heard over and over, and that is global variables. One of the reasons that we don't wanna have too many global variables, such as doing variable A equals to one. Well, I've just added variable A as a very bowl on our global scope. Something will get into a little bit later. But if hypothetically, I just keep adding variables to my environment, well, we're adding more and more pieces of memory, and these were objects and deeply nested objects. You can see the memory being used up more and more and more. Another one is event listeners. So if I have something like Element equals document dot get a lament by I D in our browser . And let's say I select the button. And with this one, I'm going to add an event listener that's going to listen on the click event, and it's going to do some function that, well, I'll just call it on Click. We don't really have a here, but it's going to have that now. This is one of the most common ways to leak memory, and that is you add these event listeners, and you never remove them when you don't need them, so that you keep adding keep out and keep adding event listeners and because they're just there in the background, you forget about them, and next thing you know, you create a memory. This happens a lot, especially if you go back and forth between single page applications where you're not removing the event listeners off the page. And as a user goes back and forth, back and forth, the memory keeps increasing. Mawr Morris More event listeners are at it. Another common one is simply using something like set interval, where you have the scent interval function that does something. And inside of here you start referencing objects, and these objects in here are going to will never be collected by the garbage collector because this set interval, unless we clear it and stop it, is going to keep running and running and running. So memory leaks there something that we have to be careful. So one example is soundcloud. You see soundcloud, which some of you may know you can listen to some really interesting artists and music. Well, they had this application that worked on a gaming device, but it was built with JavaScript and Web tools so that this soundcloud application can be run in the background of this game console. What they found out is that they had a memory leak because people put soundcloud in the background. It just kept running for long periods of time, so that this memory leak, that they had kept increasing mawr and more and more because people would enclose the application for a while, sometimes hours and hours and hours. And they noticed that they had a memory leak in their program because unlike most websites or APs, their app runs a really, really long time in the back room. So they had to fix that memory leak. I'll leave a link to this article where they explain some of this problem. It's really, really interesting if you want to learn a little bit more about it, just something to be aware of. That memory is limited. That is, when it comes to call stack and memory. Heap those air to places that JavaScript remembers or stores memory, and we have limited use of them. So for us to write efficient code, we have to be conscious to not have stack overflow or a memory leak and to manage that memory well, all right, that's enough for now. Take a break, drink some coffee, have some tea, and I'll see you in the next video. But by 16. 15 Single Threaded mio: JavaScript is a single threaded programming language. What does that mean? Well, being single threaded means that only one set of instructions is executed at a time it's not doing multiple things. And the biggest way to check that a language is single threaded is well. It has only one call Stack. This one call stack allows us to wrong code one at a time were never running functions in peril as you saw. The stack keeps growing as we push new functions on the stack, and then we pop them one at a time. Now, initially in 1995 when JavaScript was born, this made things easy for implementation and for developers using the language right, because JavaScript was Onley initially a language useful for adding interactions on a webpage such as form validations or clicking a button, nothing really required having more than just a single threat. A good way to think about it is like this single threaded means I'm the JavaScript engine, and I'm eating with one hand putting food in my mouth that is the function and then use that same hand to grab the next food. When I'm done chewing my food, I can't put any more things in my mouth until I'm done chewing. And I also can grab any more food until I finish chewing. It's single threaded one thing at a time. And because of this JavaScript is synchronous, then is one of the time in order that it appears only one thing can happen at the time. You might be asking yourself, that doesn't sound super fast, does it? Let's tackle that in the next video public. 17. 16 Exercise Problems with single threaded mio: What problems do you see with synchronous code? Think about that for a second. Pause the video if you need to. Ready for the answer. Well, with single threaded synchronous code that JavaScript and Jim runs, it's going to make it really, really difficult. If we have long running tasks, what does that mean? Imagine we are running Twitter and Twitter. Well, it's an application that we can tweet. We can check other people's tweets. We can look at. Followers are tweets are notifications are messages. Imagine if they had a function that had, let's say, a really big loop that takes five seconds to complete when that happens, if we just to use the JavaScript engine, well, I wouldn't be able to click. I wouldn't be able to scroll. I wouldn't be able to do anything. A classic example of this is the alert function. If I run alert. Hi, My JavaScript is running right now and I can scroll. I can't click anywhere. The website is frozen in time until I take some sort of action, and this mimics a long running JavaScript right on the call stack. Right now we have something like a function that's running And until that call stack is empty, I can't really do anything. That's terrible. Why would anybody use JavaScript in? I mean, it's just going to slow our pages down, right? Well, here's the thing. I haven't been completely honest with you. That's because we talk about JavaScript most of the time. You're never just using the JavaScript engine, which is synchronous we need to introduce. I had the idea of a synchronous coat and the next couple of videos. We're going to talk about what's actually happening behind the scenes where it's not just the JavaScript engine that's running our coat. We have something called the JavaScript to run time. And as we'll see, No Js will also implement something similar because in order for us to write code that we can use in this modern day, we need something beyond just the JavaScript engine. I know, I know. We're almost getting there, too, are complete picture. Hang in there because this is going to be a fungal I'll see in the next one. But why 18. 17 Javascript Runtime mio: Welcome back. It's time to talk about this diagram that looks a lot more complicated than it actually is . The Java script runtime Since, as we mentioned, JavaScript is a single threaded programming language, it has only one stack and one heap. Hence, if any other program wants to execute something, it has to wait until the previous program or function is completely executed. And if I do something that takes a really, really long time, well, things are going to be really slow for our program. That's not good. Boo. That's not nice, is it? We don't like that. And this is where javascript runtime comes in. In this case, the Web browser is working in the background while the synchronous JavaScript code is running. And it's using something called the Web A B I or the Web browser, a p I to communicate and let the Js and you know Hey, I'm back with some data, some work that you told me to do in the background. Let's dig deep into this topic. The Web AP. I comes with the browser Chrome, Microsoft Edge, Safari Firefox. All of them have their JavaScript engine implementation, and all of them have a JavaScript runtime that provide a Web a p I. These Web AP eyes are applications which can do a variety of things, like send http requests. Listen to Dom events, maybe click events on a dog delay execution using something like set time out. You said Interval. You can even be used for cashing or database storage on the browser. Let me show you what I mean. If we go to the consul here and I look at the window object, well, this is what the browser provides. This is the Web AP I that we can use so that if I scroll down here, I can see different things that the browser provides for us that our JavaScript engine can use. For example, if I scroll down to let's go to fetch fetch, that is the function to make a CDP calls. We can use that if I keep scrolling down and let's look at something fun like indexed Dhabi DB or index TB. That's actually a little database that we can use on our browser. If I go to application here, I see that I have some storage and indexed DB that the browser provides for us very, very cool If I keep scrolling down. I also see something familiar to us, such as set time out. Let's see. Where is it? Right here. Set time out. Sit, interval. All of them are provided by the browser. They're not native to JavaScript. So remember that the browsers air helping us create rich Web applications so that users aren't just sitting around waiting for our JavaScript to execute anything that could be offloaded. They'll take care of that for us in the background because you can imagine if the browser had to use the same JavaScript thread for execution off these features. Well, it's gonna take a really, really long time. So browsers actually underneath the hood use low level programming languages like C Plus plus to perform these operations in the background. And these AP eyes are called Web AP eyes because, well, they're AP eyes provided by our right browser. And these Web AP eyes are what we call a synchronous. That means you can instruct these AP eyes to do something in the background and return data once it's done. Meanwhile, we can just continue working on our JavaScript, call stack and execute functions So what are these other two things now? We're only going to scratch the surface here because towards the end of this course we have an entire asynchronous JavaScript section. But this is what happens underneath the hood. We have items on the call stack, and as soon as something comes up like set time up, that's not part of JavaScript. It's part of the Web, a P I. The call stack is going to say, Oh, I have something that's not for me Here It's for the Web browser for the Web. AP I. So it's going Teoh say, Hey, Web ap I hear it is. I don't know what to do with this. You take care of it. The Web A P I is going to say I know what set time out is. Let me take care of that and do that in the background. Now, with set time out, you usually want something to happen afterwards. So once the Web a p I is done working on it, maybe it's fetching some data from a server. It's going to say all right, I'm done with this work. Here's the data, and here's perhaps ah, Colback. Oh of what I want you to do with that data. And then the event loop is going to say as soon as the call Stack is free is going to say, Hey, I have something for you here. Would you like to add it onto the stack? And if the stock is empty, it's going to push this call back onto the stack. But that's kind of confusing. Let's actually code this and demonstrate how it works. Imagine we had a consul dialogue and in here we'll just print one. And by the way, this is a really, really common interview. Questions so hope that catches your interest. And let's say we'll also do set time out, which is part of the Web, a p I. And in here we'll just give it a function. And we'll just say, Consul dialogue to and but say 1000 milliseconds or one second and then consul Dialogue three. Now, if you've been working with JavaScript for a while, this isn't difficult. You know what's going to happen, but just to go over it quickly. If I go to my browser here, it's copying basis and I run it. I get 132 Why is that? Well, it's because we added Consul Log to our stack and we logged onto our console. And then we removed that call from our call stack, and then we went to the next line, set time out. We added this onto our stack and then immediately the JavaScript engine is going to say, Oh said Time out. That's a Web ap I I don't really care about it. I don't know what to do with it. I'm going to just send it off to the Web, a p I So this gets moved away from the call stack and gets sent to the Web. A p I. Now, we don't know what's happening on that side of things, but we just go to the next line and say, consul dot log three It's going to lock three. Now, behind the scenes, the Web A P I is going to take the set time out. It's going to start a timer that is going to run for one second, and once that one second is over, it's going to push the callback. That is what to do. Once it's done running for one second and the call back in this case is console log, too. It's like it's calling us back saying, Hey, we're ready for you. One second has passed. Can you consul log to and what happens now? The consul lock to goes to the callback. You Let's go to the diagram, goes to the callback you and says I'm the first person that's done. Can you? Consul Walk to the event loop is a loop that's constantly running about saying, Hey, is the call Stack empty is the call. Stack MP is a coal stack empty and the event loop on Lee runs once the call stack is empty and the entire JavaScript file has been bred in our case. Consul Lock three. No matter how fast the Web AP I response as the console locked to to the callback you. The event loop won't start putting anything back into the call stack until the call stack is empty and we've run through the entire file at least once. So in our case after console log three gets printed and popped off the call stack, the event loop is going to tick and say, All right, can you console log to? And that's why we get this weird pattern now. Philip Roberts, who has an amazing talk about the JavaScript of an loop and this whole JavaScript runtime system, created this tool to actually visualize this a lot better than I could explain. We're gonna go over the same steps that we just did. We see that we have function eight that calls function be function be that calls function C and function. See that goals set time out? That's a Web baby I and it's going to have a callback function that is, once it's done running for three seconds, call achieve Nirvana and achiever. Nirvana is going to console log. You are enlightened. Let's see what happens. And before I click play, see if he can predict what's going to happen and to test yourself. Let's have a look so we see right away a gets called. That's the very first thing that happens, because up until now we've just declared functions and we Onley run online. 17. That is, we execute function a so function a gets executed and we call be so we get. We add that to the call stack and then we resume call C that gets added to the call stack and then see gets called. That is, we add, said Time out to the call stack. And what do you think happens here? Well said, Time out Now get sent to the Web AP I because, well, it's a Web, a p I. And we don't really care what the Web A B I does with this. It has its own implementation, but in this case it's using this timer to just run for three seconds so that it can added to the callback you. But in the meantime, our JavaScript engine doesn't care what's happening. It's just going to keep working on the call stack. So if I resume here, you'll see that a, B and C all get popped off the stack while the timer is running. Now see what happens when this timer ends. I want to resume and look at that. It finished in three seconds, so it's going to put it back or put it into the cold back. You, in the cold back use going to say to the event loop. Hey, can I, uh, can I come back to the stack? I'm lonely. Can I come back to the stack? and the event loop says, Ho, ho. Hold on. Let me check. Is the call stack empty? Yes, it is. Has the entire file been run? Yes. Well, Line 17 is the last line. So that's the last thing that we want to run. Okay, You're allowed to go back on the stack, so I'm going to resume and look at that. The achieve Nirvana is going to get popped or pushed onto the stack. Console log gets printed, and then we pop everything off the stack. Congratulations. We've just achieved Nirvana. That's not too bad, is it? Now here's a fun little question for you. What happens if we do the exact same thing? But this time, Ad zero here, What do you think will happen? Well, if I run this, I get 13 to still now. Like I said before, this is a very common interview question. The reason that happens is that no matter how fast this set time out timer happens, it still gets sent to the web. A PR still get sent to the callback. You and the event loop still needs to check those two checks. Hey, is the stack empty and has the entire file being run in our case? No, we're still waiting on Consul Lock two. Run. And only then will I push our callback function are console log to our coal stack. How cool is that? And using this method were able to have this power off a synchronous coat that is, instead of being limited to one call stack and one memory heap. Whenever we get tasks that can be a synchronous that take a long time. Possibly like modifying Dom or making a CDP requests. Well, in that case, we can, just to send that off to the browser, the browser could just run that in the background. And whenever we're ready, it can just use it's callback, you and event loop to notify us. All right, That was a long one. Let's take a quick break and I'll see you in the next video. But by 19. 18 Nodejs mio: Welcome back. We've done a brief run through of the JavaScript, runtime and asynchronous Javascript. Now, this is something that we're going to get into a little bit deeper later on in the course. But I hope by now you should have a good understanding off the difference between a JavaScript engine and a JavaScript runtime. The way that I like to think about it is like this. You see, a Java script file is like kind of like musical notes ways for us to write music, write programs. The JavaScript engine is kind of like the musician or the composer. That person is the one that can read this music and understand it and make sense of it. And then the runtime is kind of like the whole package where we have the musician. But we also give that musician, besides the musical notes all these tools to play our beautiful music. So let me ask you this. If we're able to have different javascript Efron times because well, javascript can run outside of the browser. What do you think? Node Js ss Well, is no. G s a programming language is no gs a javascript engine. Is it a run time. Well, this kind of gives it away. It's a javascript runtime. It's not a language, it's a runtime. You see, up until 2000 and nine, you ran JavaScript code inside of the browser. That's why people didn't really respect JavaScript. They thought it was a silly toy language. Well, Ryan doll in 2000 and nine decided it would be great to run it outside the browser because up until now we only had that run time that Web ap I and the cold back. You and the Van Loop all browser based. So he created Node Js, which is actually a C plus plus program. You can actually think of it as node dot e x e. It's an execute herbal, right? A C plus plus program that provides this run time for us. And if we look at the no Js runtime, you see that it looks quite similar with our browser based runtime, doesn't it? When it comes to node Js, there are a few differences, but it works the same way as our diagram. We have our V eight engine and then we have our event loop and what they call our Kovac you and they use something called Lib UV, which again is Rin and C plus plus for us to do these asynchronous operations with the V eight engine. Now, when it comes to know J s, it does a little bit more than our Web browser. Runtime, You see, in the case of a browser, were limited to what we can do in the background, right? The browser isn't going to allow us to do much on the person's computer. You can really access, for example, the file system off the user. I mean, that would be a huge security flaw. It just runs on the browser on the tab that were currently on in what we call a sandbox environment. But a node. We can pretty much do most of the things in the background. We can access file systems. We can do all sorts of things. You see. No Js uses the Google V eight engine to understand the JavaScript, but it uses this Lib UV library, which works along to create this event loop to extend what we can do in the background. Now here's a fun thing. If I installed no Js on my computer and let's just run. Note. If I type in window here, well, I get in there. There's no window like we had in the browser. Instead, Note has something called global, and that's its global A B I. You see that just like we had with window. And no, Do we have this global A B I that we can use, which also happens to have set time out said. And terrible. That's nice, but also has some extra things that we couldn't do in a browser. And that is why node is set to be a server side platform based on asynchronous io that is non blocking. It means that it uses JavaScript but outside of the browser. But it creates this entire environment, this runtime that runs outside of the browser, and it allows us to have the same model off a single threaded model. But any asynchronous tasks can be non blocking, that is, they can be passed on to what we call worker threats in the background to do the work for us and then get sent back through the Colback you and event loop onto the stack. We were able in 2009 to have a different model to perhaps create servers. You see, back in the day, we would create a thread for each request. Something like PHP would work like this. And if what we call the threat pool that is, however much the server can work is maxed out. Well, the requests would just have to wait for the other ones to be available again. No Js change this mentality and said, Hey, we only have this one single threat But as soon as you give me a thread, I'm just going to pass it off to my asynchronous runtime to take care of it. And this simplified things a lot. Now there's pros and cons to each method, but I hope now you see the power off the runtime. How it adds on this extra feature to JavaScript so that we can finally have the capabilities we had in the browser but also the capabilities outside of the browser I'll see in the next video. But by 20. 19 Conclusion mio: hoo boy, I know that was a long section in a long section without that much coat, I know you want to do exercises and get things going, And I promise you, with the upcoming sections were going to do more and more coding. But I wanted for us to build this foundation so that we understand how the language works internally. In this section, we learned about the JavaScript engine how we can send a JavaScript file and it runs it all through these steps, including an interpreter and a compiler, a jit compiler to send us optimized code that we can run on our machines. And then we also learned about thes two very important concepts that we're gonna take with us throughout the rest of the section Call stack and memory heap and how these are used to run and execute our code. And more importantly, we focused on the call stack, something that we're going to see over and over throughout the next couple of videos and sections where we use the stack to keep track of where we are in our program, and this concept is going to be very important when we start to understand javascript deeply. We also learn about the idea of a single threaded model. That is JavaScript is a single threaded language. Want call stack, one memory heap. We learned about the limitations of that, but also the beauty and simplicity. Because we can use the JavaScript runtime to have threads in the background, that running for us, whether it is on the browser or outside of the browser, using something like no Js. And we also learned about a very common interview questions where we would do something like this. And the interviewer asked, You hate, what do you think is gonna happen here? And we should know by now why? This is why three is printed before one and two. So this is your final test to finish off this section. What happens if I run this again? But this time I'm going to run this in one second and this one in just 10 milliseconds. All right, You ready? Let's see. Okay. Is that what you expected? Did you get that right? Good. If you did move on to the next section. But I have one last question for you, and this is gonna be a little tough. So let's change this back to zero. And this over here, we're gonna change it instead to a promise dot resolve and it's just going to resolve too high. And we're just going to dot then console log to. And by the way, if you're not used to promises, I've added some videos on promises in the appendix, so you can go check those up. This is something that we're gonna learn later on in the course. What do you think is going to happen here? We have a set time out than a promise that resolves right away and Consul Locks to and then Consul Lock three, take your guests. Wait a second, because I'm gonna press center and let's see what happens is that what you expected three is a crowd Makes sense. But why did to get printed before one? Does that make sense to you? Because based on what I just tell you, it doesn't, right. How did promise get in before? One is the loneliest number. Well, in order for us to understand that and to leave you on a cliffhanger, this is something we're going to tackle in the a synchronous part off the course. But the thing is, before we get to that, we have to really understand some of the more fundamental concepts of JavaScript. I know I'm keeping you in a suspense. You can jump to the asynchronous part of this course if you're really curious. But I suggest that you wait so that we learn about the core JavaScript concepts before we see what's happening here. For now, take a break and I hope to see you in the next section, but by 21. 01 Introduction2 mio: it is time to get into the weeds of JavaScript by writing some code. Finally, we're going to be coding along to understand the fundamental principles off the language, and we will continue to do so for the rest of this course. Her A. I know everybody's happy. No more staring at slides. I mean, we're still gonna have slides, but don't worry. We'll get some quoting done, too. In this section, we're going to speak about things that underlie the way the language works and the topics that come up again and again for senior JavaScript developer interviews. By the end of this section, you will know what each of these terms meat, but also be able to use this to your advantage, to analyze, code to write better coat and just a heads up. You're going to learn some words in here that sound a lot more complex than the really are . However, they're important, and by the end of this section, you should feel comfortable discussing them and using them when speaking about coat. So enough talk, Let's get started. I'll see in the next one. Bye bye 22. 02 Execution Context mio: How do we run code in JavaScript? Well, we assign variables and then we run functions, right? That's all we really do in a language. So take a look at the code over here. Every time we run a function, let's say if we call the say my name function, we add these brackets to it, and then we're able to execute that function or run it. The JavaScript engine is going to look at this and say, Uh huh. Here's a task for me. Tell me what to do, Mr Function. And as soon as the jobs skipped, Engine sees these brackets. It's going to create something called an execution context. But we'll get to that in a second. If we run this function, say my name is going to be run, which is going to return find name, which is going to return print name, which is going to return my name. All right, that's a pretty convoluted way of doing things. But if I run this, we see that it prints Andre. So what is happening here? Well, when the JavaScript engine sees those brackets, it's going to say, Oh, I'm going to run a function and create an execution context. So the first thing it does is create an execution context, say my name and add this execution context onto the stack. Remember our coal stack, right? And then it tries to run this function and sees that Oh, this function is calling another function. So I'm going to create a new execution context because I'm going to see these brackets that's called Find My Name. And there we have it, another item that gets pushed onto the stack and then that function. Once again, the JavaScript engine is going to see. Oh, here's another bracket para brackets Print name. Let's run this function. And then this function, after it's created its own execution context is going to return the string. Andre Nagl, which gets returned to find my name, which gets returned to say my name. And then eventually the call stack all gets popped off and we return onto the screen. Andrzej Maglie. It's really weird saying my own name. Well, doing this next time I'm gonna pick a different. So if we take a look back onto our code, this should make sense. We're adding items onto the call stack, which we've talked about before, But this time I've introduced to you this idea of execution context. Now, before we get into exactly what this execution context means, I may have lied to you. The diagram that we just saw isn't 100% accurate, because the base execution context that runs is called the global execution context. This is what I mean. Initially, our JavaScript engine is going to create a global execution context. We don't see this. It's underneath the hood. But it's saying, Hey, here's the JavaScript file for you Just start reading it for me And on top of that, that's when we start adding, say my name, then find my name, then print name. And then eventually, as these execution context get popped off, the last thing that remains is the global execution context. And when the final line of our code runs and we're done with the JavaScript engine, this is going to get popped off the stack. So just from what we've learned, if I tell you whenever code is run in JavaScript, it is run inside of an execution context. Is that a true statement or a full statement? Well, it's true, right? Any time we run code in JavaScript, it's always going to be part of an execution context. That is, it's part of global or inside of some function that we called. Now we're going to get back to this topic a little bit deeper later on. But if we take a look at the global execution context, remember, that's the very first item on the stack. The first thing the Javascript engine does is to create this global execution context, and it gives you two things. First thing is a global object, and the other thing is the this keyword in JavaScript Everybody's favorite topic, right? This keyword in JavaScript. Well, we have an entire video Siris on this, so stay tuned. But to start things off global execution context gives us these two things right off the bat when the JavaScript engine starts up. So let's test this assumption. If what I just told you is correct, that means I can just give an empty file to let's say the browser and I should have a global object and the this keyword already defined without me having to do anything. So let's go to some code and test this out all right. I've created the most basic website ever. We have an HTML file that simply, says Helou and a script AG that has script Js that is completely empty. Now if I refresh year and a run this based on what I just told you, I should have, well, the this keyword and look at that. I do have access to that. This keyword, even though there's absolutely nothing in my JavaScript file, and I should also have access to the global object and in the browser, the global object is window. So I get these two things that this keyword and window, without even writing a piece of JavaScript because the browser has created a global execution context for me, and you might be asking yourself, Hold on. Are these the same thing? Well, let's test that out. This equals window. Is that true? Yep, that's true. That's the very first step that the JavaScript engine does for us. The JavaScript engine is going to create these two objects, and these two objects are going to equal to one another for now, at least. And by the way, if we're using something like note, the global object wouldn't be window. Instead, it will be called global. And to this global object we can assign variables, right? If I go back to our example and I clear this if I say variable a equals true, our alleges do Teddy. If I go to the window object now, I opened it up. I see that I've added a variable to my global object. That is a cool, steady and I can add functions and I can add different things to this global object. So once we have done this, what we call a creation face in our JavaScript engine, we then have a second face. And that second face is called the execution face where you actually run your coat. Now we're gonna expand on this a little bit, but to review when code is run on the JavaScript engine, a global execution context is created. And when you run a function, a new execution context is added. A function execution context, and we start running our coat until everything gets popped up the stack and all of our code is run. All right. I think you're sick and tired of me saying global execution context over and over, but hopefully this may tends to you because in the next video we have another difficult term to cover. I'll see you now, but why? 23. 03 Lexical Environment mio: Welcome back. Let's talk about another common term that we hear a lot. That is lexical environment. You may have heard different variations of this words such as lexical scope, lexical analysis. But what does the word lexical really meet? Well, let's ask our good friend Google. Hey, Google, what does lexical mean related to the words or vocabulary of a language? All right. Did you get that? No, not really. Right. That's the most confusing definition I've every seen. All right, so let's simplify this. What does lexical meat? Lexical environment is simply where you write something because we now know how are JavaScript engine works, that is, it looks to our code and restore our code. Where we write something is important. A lexical environment simply means that this is the way that I like to think about it. Remember our code previously, where we have our global execution context And then we called, say my name, then find my name and then finally print my name. Well, you can think of lexical environment as these little universes that you created every time we create an execution context. And if I said something like, I'm doing a lexical analysis or compilers doing lexical analysis. All it's saying is it's checking to see where the words were written and their location that is, what universe is it part of? If we go back to our code, what we're saying with a lexical environment, it's saying right now on this piece of paper or digital paper, where do we write the function? What part of the universe is it? Well say My name was written to the global execution to context. Remember that global object? Same with Find my name. Same with print name. If I did window dot print name or window dot se name, it's going to work because they were all written right here. If I had a function that was, let's say, declared inside of here that function it was written inside another world inside a function world. Right? And again, lexical means at compile time. Where is the code written in? Based on when the compiler or the interpreter sees our coat, it will know different things about that coat. In this case, this function is lexical e Inside the fine my name function the fine fine, my name world Because this way the compiler knowing where it was written can decide and make decisions us to where to put things and what actions to take and what function a has access to in that world. And there are a lot of lexical environments, right? All these different planets. Well, the way I like to think about it is this in JavaScript, Every time we have a function, it creates a new world for us. Inside of that function, we are shut up into that planet. Every time we added onto the call stack and inside of that planet, we can do different things, have different information inside of them. And as we'll see later on, they can communicate with each other in different ways. So based on what we just learned, if I told you execution context tells you which lexical environment is currently running, does that make sense? No. Yeah, right. This execution Thanh text is going to tell me which lexical environment which planet is currently running. And that's how things work in JavaScript. In JavaScript are lexical scope. And don't worry, Scopus, something will go later on. But you can think of it as a lexical environment where code is written so lexical scope, which is the available data and variables where the function was defined. That is where we write it determines are available variables. Now where the function is called, which is dynamic scope. So it doesn't matter where we call our function, It doesn't matter that find my name gets called inside of say my name because find my name was Lexical e scoped, that is, its lexical environment is global. It was written out here with no indentation that is in the global scope. It will have access to certain things based on that property. And this is something that we're gonna get into a little bit more. But to close out this video, what is the first lexical environment that we have? Well, the very first lexical environment is the global lexical environment where we write our coat. All right, I hope your brain doesn't hurt from these terms, but we just covered too. Execution context and lexical environment. Let's go on to the next video I'll see in the next one. But by 24. 04 Hoisting mio: remember this diagram? Well, in this diagram, there is an important piece missing. I told you about the creation face. That is when we set the global object and the this keyword and they equal each other. And then I told you that the second face, which is the execution face, is while we just run our coat Well, in this diagram, there's an important piece missing. This white line actually divides these two phases. And in the creation face, we have a one more step. We have something called hoisting. So let's look at what this does. Hoisting is the behavior off moving the variables or function declarations to the top off their respective environments? During compilation, face variables are partially hoisted and function declarations are hoisted. All right, Did you get any of that? No, that was a little bit confusing. So let's go through some coat if I create a console log here and just to make things clear and I'll just say one like this so we know what's happening and in here we'll have a variable teddy and Teddy will equal to equal to bear cute name, and then we'll also have a function and Let's say sing and the sink function sings beautifully. Oh, la la la beautiful song now hoisting what it does during the creation face of our global execution context. Well, it does something like this. What do you think will happen if I cancelled? All log, Teddy Here, Fight, Run This I get on defined for Teddy. Okay, now, this might not surprise you. And if you've been working with JavaScript, this is normal, right? It's on to find. But in most languages it doesn't work like this because in JavaScript I can also run the function like this sing even before I have written it down. If I click run, I see that I have Oh, la, la la And this is due to hoisting. It is the JavaScript engine allocating memory for the variables and functions that it sees in your code during the creation phase before it executes it. So what happens underneath the hood is that during the creation face, the JavaScript engine is going to look through the code. And as soon as it ceased to things either the of our keyword or the function keyword, it's going to say, Oh, let me allocates a memory cause this guy over here, he's going about, he's he's gonna need some memory. So it's going to do something like this. It's going to say, Hey, variable Teddy, that's going to be on defined I don't know what it is yet, but I know that we're gonna have to have a variable teddy, So assign it undefined for now, and that's an actual JavaScript type. It's a reserved war because it's something in JavaScript and then same with function. It's almost like this function gets moved up here saying, Hey, there's a function here. Let's add this to memory because, well, we're gonna use it. And underneath the hood, this is what it might look like with hoisting where Teddy is now undefined because the JavaScript engine when it executes the code during the creation face, we already knew that Teddy was gonna be a variable. We don't know what it is yet it is not bear, but it's undefined. So gives us on to find. So that's what I mean. When I said very bulls are partially hoisted, we hoist the variable, but not the right side, not the actual value. We just assigned it on to fund functions are fully hoisted. That means this function declaration was, during the creation, face assigned a location and memory. And you can think of it this way where any time we call sing, we know where this piece of tax is in memory, so that if we call Singh, we can run that function. And as you can see, it's working. Now let's test some of our assumptions that I just told you if we move this back to where it waas and we remove Teddy undefined from here and go back to that code. What I told you was that as soon as the JavaScript engine sees var or function, it's going to hoist it and make space for it in memory. So what if I do something like this where I add a bracket to the function over here so the JavaScript engine no longer sees function as the first word. Instead, it sees a bracket, then a function. What do you think will happen here if I hit play? I get a reference there. Sing is not defined because it doesn't hoist it because the first thing it sees wasn't a far wasn't a function well this was not hoisted. So we get sink is not defined. What about this? And this is something that we're going to talk about later on. But if I changed us to eight cost, which is a new ES six syntax now with this cost keyword or let that doesn't get hoisted, remember, the rule is it's either Ivar or function. So as soon as it sees, let it actually will air out. Now in this ripple, it won't give me an heir. But if I open up the consul here and copy our code and run it, I'll get Teddy is not defined. And in most languages where there isn't hoisting, that's what would happen. We wouldn't be able to use variables or functions before we've actually written them. The compiler won't know anything about it. No, unlike what I told you initially, the compiler isn't actually moving these lines of code. It's not physically moving variable teddy all the way up or function all the way up. It looks like it may, but what it's doing is simply having one passed through the code and saying, reserve memory or a sign memory into this space. If we look at our diagram with hoisting during our global execution face. We're simply saying, Hey, we're gonna It looks like we're gonna have a few functions in a few variables. Can you allocate some memory for us here? Just get us ready for the program about to run. Therefore, when we see console log Teddy here, the JavaScript engine is during its execution phase is going to say, Hey, can you grab Teddy from memory? And when it looks a teddy in memory, it's assigned undefined from now because it hasn't been assigned a new value. And that is a key distinction, especially when it comes to functions. We have function declarations like the one that we saw here were function is the first word on a line or we have something like function expressions. That is, we can create a variable sing to that equals function. And this function is going to sing something else. Ooh, la la. There you go. This is a function expression. This is a function declaration. No. What do you think this piece of code does when it comes to hoisting? Well during the creation face, this variable is going to be hoisted up here and it's going to be assigned on defined so with a function expression until the execution face reaches it, that is, it has hoisted everything. And now we're in the second part where we start running the code line by line. Well, with a function expression is on Lee going to be run after it was defined. So I can't do sing to here. I'll get on air. It's not a function, but if I move this line after we assign it, it's working for us. And if we go back and just console log sing to instead of running it with the brackets, I get to undefined because sing to was hoisted. So to review, with our global execution context, we have a few things that happened. We have the global object and this object during the creation face that gets assigned. And then during the execution face, we run our coat. But it's important to remember that during this creation face, we also have this act off hoisting something that's quite unique to JavaScript will remove any time we see the function or the bar keywords. As the first items on the line, we allocate space for them in our heap to make sure that the JavaScript engine is ready for the execution. So now that we've gotten that done, let's do a fun little exercise. 25. 05 Hoisting Exercise 1 mio: Welcome back. Let's try a fun little exercise. And before you see my solution, try to solve this yourself. If we look at this piece of coat based on what we learned about hoisting, what do you think it does well here? If I just Consul Dialogue one and run it, we get to that makes sense. During execution Face, the very last line was to assign 2 to 1 so console log one is too confusing. But that makes sense during hoisting. What do you think happens well during hoisting? One is simply going to equal on defined. So when the JavaScript engine sees a second line with the VAR keyword and the same variable assigned to it, it's actually going to just ignore this line. That is, it's going to say No, no, no, I'm good. Ah, I already have one equals two undefined. I'm going to just choose to ignore you because we've already assigned want to equal undefined. Okay, what about this? What if I have a function? Hey, you know, I'm being very creative, more my function names here, but they're with me. I have consul log high that's functioning, and I also have another function? A that says, by what do you think happens or sorry, Let's do function a again. So we have the exact same functions. And if I run a here, what do you think happens, Pause and think about with variables. They're partially hoisted. So we have undefined to that variable with a function declaration, we fully hoist it so something gets put in memory during the creation face. But we have two of the same functions Based on what you know about the JavaScript engine that you've learned up until now. What do you think's gonna happen? All right, enough suspense. Let's find out. You get by and that makes sensory. During the hoisting face, we look at the function, the compiler says, Oh, yeah, yeah, yeah, I'm going to hoist this and I'm gonna put this someplace in memory for us, and then it keeps going to the next line and says, Here's functioning again. I'm going to put this in memory and because this even though this is the same thing because we're doing it one after another, it's going to rewrite that place in memory to include Consul log by so that in this case we've lost the ability to say hi with this function we can on Li se But this is the case even if I put the A here or even if I put the A here and I hope by now that makes sense to you. Now I have one more exercise for you and this is a tricky one because up until now we've talked about the global execution context in this global execution context has the creation phase and the execution face. But this actually happens any time we call a function. Any time we call a function, there is a creation face and an execution face where there's hoisting involved. Let me show you in the next exercise. 26. 06 Hoisting Exercise 2 mio: Welcome back. I have another tricky question for you. And if you are able to get this, you've pretty much mastered hoisting. It's a really difficult question that comes up quite often in JavaScript interviews. Looking at this function, I've created a few things. Well, we have my favorite food grapes, obviously. But then I changed my mind, and I have a food thoughts function, and this food thoughts function is a function expression where I log my original favorite food. And then I changed my favorite food to sushi and then I console, log my new favorite food and then online. 11. We're going to execute and run the food thoughts function before I click. Run here. Based on what you know about the creation. Face the execution face about hoisting. What do you think is going to be locked here? Pause the video. If you want to try to sell yourself. Otherwise I'm going to click Run, Let's find out. Original favorite food. Undefined. New favorite food. Sushi, huh? Is that what you expected? I bet most of you thought the last fine in our function that is consul locked new favorite food to equal sushi would work But I bet this is surprising to some of you. Why do we get undefined here? And this goes back to what I said in the previous video that is, hoisting happens on every execution context. Any time we run a function, a new execution context gets created and we have to go through the creation face and execution phase again. So let's see what happens here. Well, the first line gets hoisted, so favorite food of the top becomes variable. Favorite food equals undefined. And remember, the JavaScript engine isn't actually moving these lines up. I just want explain what's happening, but we assign favorite food too. Undefined Favorite food now gets assigned to undefined, and I may have for gotten the very bulky word here, so that gets hoisted. And then we go to line for and line for. We see a variable so fruit thoughts also gets hoisted, so variable fruit thoughts is going to equal undefined. It's a variable, and we keep going. Keep going, keep going. There's no more very of our There's no more function at the beginning of the lines. So there you go. Our creation face is done. So now, during the execution face. It's almost as if we don't need the variable keywords anymore because they've been created during the creation face. So now we start executing the coat. The first execution that we do is favorite food equals two grapes, all right, and then we have through thoughts that gets assigned this entire piece of function. We don't run this function. It just says, Hey, fruit thoughts is going to equal dysfunction and then online. 14. We're going to run this function because the JavaScript engine is going to see these two brackets now. As soon as we run this function, a new execution context is created. And inside of this execution context, hoisting happens during the creation face. So it's going to say, Hey, I see variable here in this low world that were in and there's favorite food here, so I'm going to hoist that up, and by I I mean the JavaScript engine, and it's going to hoist it up and say Favorite food equals two undefined, and that's it. That's the only variable and function that it sees. So now it's almost as if during the execution face you're doing this. You're logging original favorite food is favorite food, which is undefined. Then favorite food becomes sushi where we log favorite food. No looking at this. I hope you understand what's happening underneath the hood, and we're going to talk a little bit more about this idea of functions and scopes and what really happens here later on. But you might be asking yourself, Isn't hoisting confusing? What happened to being predictable with our code and making sure that the compiler as well as humans, can understand our coat? Because it's predictable? And they are arguments about whether you should even use hoisting and whether hoisting is bad practice? Because we want to make code predictable. Remember, and personally doing things like this makes your code very unpredictable, and I recommend avoiding hoisting if you can, and you can do that well by not using the of our keyword. So if we go back to our code the way it was before like this, we can just simply use cost and let that came with the S five or S six something. We're going to talk about a little bit later on, and that's going to give us an air because right now we're trying to take advantage of hoisting. And while favorite food is not defined because it's defined here and we cash that error ahead of time because now, as a developer, you're going to see all right, this doesn't make sense because we're no longer using hoisting this console log at the beginning. Well, this is not going to work, so maybe we need to rewrite our code to have it make more sense instead of just relying on hoisting. But it is a pretty important concept in JavaScript. You're going to see it used all over the place. But I hope this is now a little bit easier for you to explain to others and work with yourself. I'll see in the next video, but by 27. 07 Function Invocation mio: Welcome back. Remember what I said before? Programs are simply assigning memory, for example, assigning a value to a variable and then running a function for the program to do something with those variables. That's all Programs are and without functions are programs wouldn't do anything. This is an important concept in all programming languages. And as you'll see in future videos, functions give us some amazing powers in JavaScript. So let's define functions and some of the common terms around them. We already touched on the fact that we have function expressions and function declarations . A function declaration is something that starts with the function keyword. And let's just create a function India and this function will simply console a long warm because it's pretty warm in India. No function expression, on the other hand, doesn't start with the function keyword. Instead, came look like this and say variable Canada, and that's going to equal function. And inside of this function it's console dialogue, and Canada is very cold, the least where I'm filming right now. It's extremely cold, and that's a function expression, and we've learned about this and how function declarations get hoisted. Functioning expressions, don't I could also write this with an arrow function and do something like this if I wanted to. We'll have the same effect now with our functions, we can call them right and the terms here sometimes very. But you can have function. Let's comment this out. We can have function invocation, calling a function, or you can even have execution function. And what that means is, we're telling our JavaScript engine do hey, run our function. We've put these functions in memory or a lease. We've assigned her variable, and now we're ready to do something with our program. So we do a function invocation by simply running the function with curly brackets. And as soon as the JavaScript engine sees this, it says, All right, what do we do? We create an execution context. Same with India. Going like this, I invoke a function I call the function. I execute the function. If I click run, it's working, and this is pretty basic. Nothing new, right? I wanted to go over the terms just so were clear for the next few videos. When I use these terms and to review when it comes to the Canada function, well, this function is defined at runtime when we actually run the function or call the function or execute the function or evoke the function. That's when we defined what this function does versus India, where this function gets defined at parse time. That is when the compiler initially looks of the coat and starts hoisting in allocating memory. Now these functions, when they're executed, have another piece to them. Let's have a look when a function is invoked. Well, we create a new execution context on top of our global execution context, and we get a few things. We get the this key work, which we've already talked about, and we'll define it a little bit better later on in the videos as well. But unlike the global execution context that gave us a global object that equals to this. Instead, with a function in vocation, we get something called arguments, and that's another key word in JavaScript. Let's have a look of this arguments keyword. If I scroll down here and let's start off with a new function, this function is going to be called Mary, and it's a function that marries two people, person one and person to it. has parameters, and inside of this function will just simply console dot log arguments, which, according to what I just said we should have access to because when we invoked this function will get passed. An arguments object and just for fun. Let's also return from this function a template string that will say person one is now married to person to How cute is that? All right now from here. If I run the Mary function with, let's say, marrying Tim and Tina Fire on this Ah, yet Tim is now married to Tina. That's great. But look at that. We get something from this console log arguments. Let's right, arguments in here And just so we can be a little bit more clear as to what's happening. And if I run this, we see that this arguments keyword gives us an object with the first index being Tim in the second index or, in this case, key being Tina. So we get that special object very interesting. Now, if what I told you is correct, that means we don't really get arguments in the global object, do we? If I run this, I'll get an air arguments is not defined because, well, arguments is only available to us when we create a new execution context with a function. All right, so we got the arguments Object, But you might remember something from our previous videos. Remember this? We talked about how to help the JavaScript engine optimize our coat. And I told you not to use arguments, and I kind of gave you a vague answer as to why that is. Well, in the next video, let's have a look at why that is. 28. 08 arguments mio: Welcome back now, I said. That arguments is a little bit dangerous to use. Why is that? Well, because arguments looks like an array, but it's not really an array. So there are many things that you can do with the arguments key Ward that might make the compiler or the JavaScript engine less able to optimize your coat because you can't really use a ray methods on this Kenya. I mean, look at it. It's not really an array, is it? And with the new JavaScript, they introduced a few little tools that we can use so that we avoid using arguments because there are some cases where we might wanna iterated or Luke through arguments instead of just accessing them regularly. One way to go about it is to say, Consul dialogue and use the new array dot from Method. And this if we give it something like arguments in here will create an array from whatever we give it. So if we run this, you see that I get Tim and Tina in an array form so that we can now use a ray methods on arguments. So that's nice. Another way to do this is to Let's have the Mary function again. But this time use default parameters again. Something that we got with the S six. And here let's call this function Mary to instead of using person one and person to we use the spread operator to say arcs or arguments. I can't really use arguments because that is a reserved ward and JavaScript. And this time around I'm going to call the arguments arcs, which we're gonna console log, and we'll keep Consul Log Array from the same way. If I Ron Mary to in this case and I click run, I hope I get an error because person one is not defined in our template string. Over here we have to access our array. So let's say our eggs the first item in our argument and the second item in our arguments. If I click run, there you go. We now have arcs as an argument. So with modern JavaScript, you most likely want to avoid arguments. It's one of those tricky things that was initially added to JavaScript that caused a lot of problems and headache. But using the techniques that I've shown you, we can actually convert that into an array like object so that when you do, those operations will be helpful for you. By the way, I know we went on a bit of a tangent, but we are talking about this arguments object that we get and do finalize our understanding. Oh, this arguments object. Remember something that we get on each execution context. Let me ask you a question. Five. Remove this Mary function and just go back to our Canada and India functions. If inside of this India function, I say console dot log arguments, what do you think I will get going to comment out the Canada function and just Iran. India. Take a guess because I'm gonna hate run, I get a nem PDI arguments object we can still use Thea arguments object even though it's empty even though we didn't pass any parameters because on each execution context we create and you arguments object. All right, let's learn a fume or interesting characteristics off functions I'll see in the next one. But why 29. 09 Variable Environment : Welcome back. We learned that there can be many execution contexts, but you might be asking yourself, what about variables that are created inside of these individual execution context, that is variables inside off functions. And we have a place for that. On top of the execution context of this and arguments, we also have a little space over here called Variable Environment. This is a place that variables can live in in these different stack world. I mean, they all technically live in our JavaScript engine memory, but they need to know how they relate to one another. Some functions have access to their certain variables, and some don't remember what I said before. You can think of each execution context like its own little planet, its own little universe. These worlds don't really communicate with each other or no off each other. Well, kind of for now. So what type of thing do we have in this variable environment? Let's have a look at a little example. Let's say I create two functions we have function to that has variable is valid. We're not assigning it to anything. We're just declaring this variable. We have function one in this function will have once again variable is valid and we'll give that valid equal to true. And then we'll also call the function to in here Finally will also add a variable is valid here. Well, say false in here. And then finally, online 11 will call the one function all right. That looks extremely confusing, but let's go step by step and see what happens when it comes to variable environments. The first thing that happens well, we have function declarations. So these get hoisted and put at the top, allocating memory space for them. We also have is a valid, which is a global variable and is assigned and undefined when it gets hosted. Then we start running or executing our coat during the execution face. The very first step is line 10 where we assign false two is valid. So in the memory space we change undefined to now false. So that is valid equals two false. The second step is lying 11. Where we run one, we invoke the function and a new execution context is created on top of the staff. If we can think about it like this, we just created a new execution context. The third step is well, we go into the function and we have Line six over here, where we have the variable is valid that will be put into the new execution context. That is, this variable will be put in the local environment or the variable environment, and then we run function to. So a new execution context is created and on top of the stack we add to. So now we go into the to world and in the two world we have a new variable that's being declared. Initially. It's undefined. But then when we actually see this well, nothing's being assigned to it. So this remains on defined. So let's think about this in terms off variable environment in the global environment, that is, remember, at the very bottom of the stack, we have the global execution context. Well, we have variable is valid equals two false. So this is going to have false as it's variable in the one execution context, the local environment or variable environment, is going to have a variable called is Valid that is going to equal to true. It doesn't really care about what's happening in the global execution environment or the global world. It only cares about what's inside it for itself. When we go to two, well, two we already have is valid as well. But this is valid is going to be on defined. So each of these worlds carry information or variables in data that they have access to. And when we finish executing the functions that is lying to gets done in function to, well, we pop off this off the stack and that memory space for is valid is gone, and then we pop off one, and that memory space for is valid is also gone. And then finally, once we're done with the year, we can clear everything and all the memory is gone from our program. Now this variable environment, a place where we store information. And by the way, when I say store information, some of this information can be on the actual call stack or the execution context. Remember, this is just a call stack, or it could be a reference to somewhere in the heap in the memory heap that perhaps we might have an object. Now, this is something we're gonna use in some upcoming videos But keep in mind, each execution context has its own variable environment. Let's learn more about this in the next video nobody. 30. 10 Scope Chain mio: Welcome back. Welcome to her favorite function once again the same my name function that runs Find my name that runs print name and then finally, Princeton A. Now there's another piece of the puzzle. There is another part of the execution contexts that we have not discussed. And I know I know it seems like a lot, but trust me once you get this stuff and I know I'm repeating a lot of things, but by repetition we should have this ingrained in our brains for the rest of our career. So bear with me. I know I say execution context 1000 times in a video, but hopefully I'll stick to you even though you might get a little bit annoyed with me now . This other piece of the puzzle when it comes to the execution context that we haven't discussed it is that each world that is each context has a link to its outside world or a link to its parent, and this outer environment depends on where the function sits. Lexical e. We know that word, right? Lexical e means where the function is written, so let's figure out what that means in here. If I created a new variable. Let's call it a variable X that equals X. All of these functions Fine. Name, print, name. Say my name is going to be able to access this variable this global variable If I run console dot log X here in fine name even though fine name gets added to the stack of the very end. If I run this, I don't get any years. I have access to X. All of these functions have access to the global scope. Let's see how this works in a diagram. All of these functions have a global lexical environment that is, they're written in the global space to not inside of another function just on the main page . They just get attached to the window object or the global object. So all these functions have their own variable environment. They have access to each their own variables. But they also have this little link what we call a scope chain and this scope chain links and gives us access to variables that are in our parent environment in this case, the global environment. So when we assigned variable x two x when I ran print name Consul log X. It first looks in the variable environment and on Lee sees the very well see here and says , I can't really find this year. Let me go up the scope chain or, in this case, down the scope chain and see if it's attached to my global lexical environment. And it finds the X variable all the way down here off the screen and is able to console log X again. If we go back to our code console, Log X works because, well, we can go down the scope chain. The JavaScript engine is going to say, All right, I have variable B but don't have very blacks. Let me go into my parent environment. Oh, and I see X here. I can log it, and by the way, in the diagram, the console log was here in the print name. But it's the same thing. It's going to work both ways now. What I just demonstrated to you is called scope or static scope, to be exact. Remember this phrase that we saw before in JavaScript are lexical scope that is available data Variables where the function was defined determines are available variables. That means variables in our local environment or variable environment, and it doesn't really matter where the function is called. No matter where the function is on the execution stack. What matters is where the function is written, and there's an interesting characteristic of that, right. This idea of lexical scope, which is also called static scope in a language, means that Onley by looking at the source code, we can determine which environment the variables and data are available in. And that's what the compiler does. The JavaScript compiler looks at the code and attaches all these scope chains before it even runs the code. How cool is that? Because we have a lexical scope. We know what environments are linked to each other, and we know what data can be accessed by which function. And the scope chain starts where the variable is defined and goes all the way down to the global context to see if the variable exist. So that's what scope means. Scope is, Hey, where can I access that variable? Where is that variable in my coat? Let's take this example a little bit further. Let's say I have a new function. Well, it still does the same thing, but it's written lexical e in a different way. If I run, see my name here and I invoke this function and I click to run, I get function. Find name. That is because when I run this function well, it returns this part of the coat, which is a function, find my name. So, using that logic, let's invoke this function once again by adding another curly bracket. Remember, this gets turned into the fine name function and this fine name function. I'm going to invoke it with a curly bracket. And let's remove this consul lock because we don't need it right now. If I click run, I get function print name. All right, so I'm here now. It's returned this part. Let's run this function again. I'm going to add another curly bracket. And again we're just using whatever the JavaScript engine does to run our function. If I click run hooray! We got the same result as last time. But as you can see here, these are all lexical e scoped different that before right previously, all these functions had global lexical environments. What do they have now? If you wear the JavaScript engine And you are looking at this code. You haven't even run this code. How would you link the chains together? Well, it will look something like this. Instead of having the links like this, you'd have them like this. What we call a function lexical environment that is find name is written inside of say, my name function. So find names function lexical environment is say my name and print names function Lexical environment is find name. So the scope chain goes down like this so that hypothetically print name has access to be And a find name has access to be and a Let's test this up. If I go to print name, I can console dialogue, See? And if I run this awesome, I get c. That's great. What if I console log Be according to the diagram I have that scope Ching where I can access the parent environment. So if I run this Hey, look at that It works. What about a If I run this beautiful so by running console dialogue A I am going up the scope chain Seeing hey is a hear No, don't have it. Keep looking And then going up the scope chain to say my name says, Hey, do you have a here? Yep. I have it. Here you go. What if I remove this and instead use it here? Can I look for a If I run this? Yep. I can look for a but what about C? No, I get a reference Air. Sea is not defined. Why is that? Well, if we go to the diagram, see is up over here. And when I do console log in fine name, it's going to look in the variable environment says no. No, See here, keep looking. And then it's going to go into the say My name's variable environment says, Hey, let's see here. No, keep looking and then it goes into the global environment says, Hey, let's see there. Nope. So it gives us a reference there. I have no idea what you're talking about. Ah, you're doing something strange here. I'm going to throw an air. This principle in JavaScript is going to be used throughout the course, and it's very, very important. So if you need to watch this video again, go ahead and do it. But I hope you get this point in this video, we learned that the global scope is the outermost scope. So variables declared outside a function are in what we call global scope, and they can be accessed in any other scope that is inside of the functions. We can always access global scope now local scope. That is any scope that is local to a function now. Variables declared in this local scope are accessible within the scope as well as any scopes surrounding. And that's all scope is. It just defines the accessibility of variables and functions in the coat. It tells us what we can access while we can not. And just as a little refresher, remember, undefined is an actual type in JavaScript, undefined. When we get something undefined, it means, yes, we have this variable, but it's not assigned anything right now versus something like a reference there says Hey, this is completely on declared scope. Chain can't find anything by the way back to this slide. Remember how I told you that evil and the with statement are not a good idea? It doesn't help our JavaScript engine optimize our code Well, it's because of the issues that it has with scope, because with Evel and with You can actually change how scope and scope Jane's work internally in JavaScript and that makes things difficult for us because we have lexical scope. The compiler can just look at our code and create the scope chain and understand what's going to happen. But if we start changing those around with something like Evel, it's going to trick the JavaScript engine and it might have to de optimize some of our coat . All right, let's take a break and I'll see you in the next video. But by 31. 11 [[scopes]] mio: Welcome back. I want to show you one little diagram to finalize this point. When a function is cult, an environment is created for the new scope that it enters right. This little world that it enters that environment has a field that has its own variable environment, but also another place that points to the outer scope. And then that arthroscope points to its outer scope until a hits the global scope And the JavaScript spec actually has this internally, where it's bracket, bracket or square brackets, square brackets, scope or scopes. So let's test out this idea now in Google Chrome Developer browser, you can actually access this property. If I create a function here. Let's just call it a If I go into the window, object now and look for a let's scroll down. There it is. If I click over here, I have a few things. But if I go down, look at that. I have something called Scopes and inside of this scopes, we have type global. Why? Well, because the scope of function A. That scope is global, so this is pointing to the outer parent. So we have our variable environments in function a. And as soon as we can't find what we're looking for, we're going to look inside of scopes to our ardor environment, which in this case is the global type, which is the window object. Very, very cool. Alright, it's time to do a phone little exercise. 32. 12 Exercise Weird scope mio1: Welcome back. Let's do a fun little exercise that is a little bit tricky as well. Let's say I have a function called weird and dysfunction. Weird has a height off. 50. Where do you think this height, property or height variable is located? Let's run this and see what happens. I'm going to run. Weird. Get undefined because it's not returning anything. But if I return height, I get 50. Okay, but is height being created in the variable environment off Weird? Well, no. And that's because JavaScript is a little bit weird here. This is actually called leakage of global behave ALS, because what JavaScript does underneath the hood is that it looks at height and says, This isn't in my nothing's been declared. I haven't seen a bar or a const or a let keyword, so I don't have it. Those key worst tell JavaScript to put those in our variable environment, but it's not there. So it's going to go up the scope Jane to the global environment and says, Hey, is there such thing of the height and the global environment is going to say No, I don't have it, but it's not throwing an error, is it? And that's because the global environment actually sees that this doesn't exist and will create it for you. Just as it's looking up the scope chain now, don't you think that's weird? That doesn't make any sense, right? This is something that in the past with JavaScript you could do, and it caused a lot of problems. So now we have something like use strict that if I added to the top of a page, you may have seen things like this. You strict was introduced as a way to prevent JavaScript for doing these weird, unpredictable etch cases because Java script was written by a program. And there's no such thing as a perfect programming language or a perfect program, and you strict allows us to avoid these pitfalls that it shouldn't happen. And you see over here as soon as I used you strict, it's going to say height is not defined because it's going to go up the scope chain, and it's going to say no, you've never really declared this variable, have no idea what you're talking about, so I have to use variable or let or const to declare that variable all right. JavaScript is weird. Here's another one. Let's say we have a variable. Call it Hey, another creative name by me. And in here this variable will have a function. But instead of anonymous function, it's going to have a name. Let's call it doodle. And this function will let's say do something. It's not really doing anything, is it? Now if I run Hey, hey. And actually licious Consul lock here for just return. Hey, hey. If I run this well, that's expected. But what if I run doodle? What do you think will happen? Take a guess. Well, if I run this, I get a reference air. What does that mean? That means it's nowhere to be seen in the scope chain. This is because the doodle function is actually enclosed in its own scope. Doodle gets actually added to its own execution. Contexts variable environment. Very weird. Right. But that's a little gotcha over here, where we can't access it on the global scope. We can Onley access it here. All right, I hope that didn't confuse it too much. Just a fun little tricks to confuse your programming friends. All right, I'll see in the next one. But why 33. 13 function scope vs block scope mio: Welcome back. Let's talk about function scope versus block scope. These are very important terms when he comes to, well, any programming language, remember, scope means what variables we have access to, and JavaScript has function. Scope right. Every time we create a function, we create a new execution context, which has its own variable environment. But you see most other programming languages have something called block scope. So what's the difference? Well, it means that with a function scope if I created, let's say an if statement and let's say if five is greater than for which it is, and I create a variable here cold secret and I have a super secret password because JavaScript uses function scope, I can actually access the password like this. If I click run, I'm able to access this password because this variable is functionally scoped. That means we Onley create a new scope, a new environment when there is a function. If this was a function well, in that case with function scope, we can't access the secret. Now a most other programming languages, the use block, scope and block scope is well, any time I see a block of code that is thes curly brackets. I'm going to create a new world, a new environment in other programming languages. If I do secret here, I wouldn't be able to access it like I can. And JavaScript saw this and said, I want to be able to do block scoping too. How can I do that? Well, with es six, they introduced the let and the Const keywords and they allow us to use block scoping. Let me show you if I run this Oh, I can't access secret if I add the let keyword Oh, no, The secret. Well, it's definitely secret now. I can't access it. You see variables declared inside a block scope such as and s statement or let's say, four loops can be accessed from the outside of the opening and closing curly brackets when we use function scope when we use things like bar. But now with the introduction off, let em bar we can do this, which gives us a little bit more power. Now that doesn't mean that you should never use far. I mean, most of the time, you probably should just use let or constant, but let and costs are just block scoped alternatives for very bold declaration. So let's see how this can be useful to us in the next video. We're going to do a little exercise and let's see if you can solve it. It's gonna be a hard one. 34. 14 Exercise Block Scope mio: Let's do a fun little exercise. And, yes, I know I call all exercise is fun, but it's fun, right? And we get to coat. All right, let's say we have a function here and dysfunction is going to be called Loop another original name. And inside of this loop will have a for loop that has variable I equal to zero. Let's say I is or should be, less than five. And as long as it's less than five, well, we're gonna keep incremental and we're going to loop and just console dot log. All right. And after this four loop again within dysfunction, I'm going to also do Consul dialogue. Hi. Now let's add a final tax here and see what happens when I run this. What do you think's gonna happen if I run? Well, nothing. Because But your question. I haven't really invoked the function. So let's do that. I'm going to loop and run. All right? Does that make sense? We declared a variable, made it zero. We loop through everything. And once we're done with all of this, we finished everything. I becomes five we do is five less than five. Nope. Then I'm going to ignore this skip over this block and go to Consul Lock. And because I is now five, our final value is five. But what if I change this to a Let what would happen now with block scope? Think about it. Pause a video if you need to. Otherwise, let's see what happens. Going to hear? Run! Oh, I get a reference there. I is not defined. And why is that? Well, because we're trying to use I outside of it environment. It's block scoped. Great. So the environment that it's in well, it's inside of these curly brackets, so we can't really access it outside of those brackets. So this isn't going to work now. This may have unintended consequences. Maybe you do want to print this properly, so there are cases where the variable keyword is still useful. But it's nice to know that we now have a way to have block scoping whenever we need it. So to review block scoping means declaring a variable not just inside a function but around any curly brackets, like if statements or loops. Now the variable itself let I is actually still in memory, but the engine just won't allow you to access it before, like it was when we used var. This way we get to keep our mental framework of execution context and variable environment , but also have this little let keyword and constantly word that give us some of the powers of block scoping. All right, I think that's enough for now. Take a break and I'll see you in the next video, but by 35. 15 Global Variables mio: Welcome back. I want to talk quickly about global variables and how evil they are. I mean, if you were paying attention, you might be asking yourself, Andre, why don't we just do global variables all the time? Remember how we had global lexical environment? Why don't we just declare all our variables into the global scope? Because whatever function we use, well, we'll have access to all those variables. Wouldn't that be nice? And everything has access to everything. And we don't have to worry about undefined, undeclared variables instead of having something like previously where we have these weird scope chains, Doesn't that make our code more complex? Harder to understand? Well, there's a few issues with what we call polluting the global name space having too much data on our global execution environment. Remember, we have limited space, limited memory, right, and we talked about how memory leaks happen when we just have too much stuff in our memory heap that eventually it just overflows, making things slower and slower and slower until our brothers crash. And one of the main ways that we do that is with global variables. But now you're thinking, Well, I'm only gonna declare a few variables. I'm not gonna just have so many that I'm gonna completely crash the Web browser. Well, there's another issue here with global variables and why we want to avoid or minimize our use of global variables. Let's have a look at an example. You see the issue with global variables is that we can have very bold collisions. For example, imagine if we had multiple scripts here which oser applications get larger and larger. We have more than just one JavaScript ball, right? And let's say we have in here a variable Z that equals to one. We have variable Z Z that equals to two. Make sure I can spell here and let's say we have variable Z z Z equals 23 And let's just add another one. Let's say for we don't need this script for now. And you know what? This one I'm going to leave it at Z and let's say 10,000 I'm going to save and I'm one to refresh. All right, I refresh the page. Now, if I look at Z here, what would I have? Well, I get 10,000. I've overridden whatever I had at the top over here that is Z equals one because we had a collision. And the way this works is that in the HTML file, all these script tags get combined essentially into one execution context. Great. So everything gets bunched up together. Everything is on the global execution context, and they override each other if there's any duplicates. So this creates a lot of possible bucks where we write different variables and maybe we think we're being safe here. But somebody on another file over rights, one of our super sukit important variables. So how do we solve this issue? And we have an entire section on this topic on the idea off modules. But I want to scratch the surface here in the next video when it comes to Scopes. And that is how we use will be no now about scope and scope chains to avoid the issue of global variables. I'll see in the next video, but my 36. 16 IIFE mio: welcome back. So global variables are back. They can cause a lot of issues. And how can we minimize them With modern JavaScript? We have things like E s modules and module bundlers, something we're going to talk about a little bit later on in the course. But before we had those things, JavaScript developers used what we know now about the language itself to avoid this global variable issue. And it's called an iffy or an immediately invoked function expression. Let's see what it looks like. And if he is a function expression that looks something like this here we go confused. Don't be because we already know this. And we should already understand what the JavaScript engine is going to do with this coat. You see, if he's are a common JavaScript design pattern used by a lot of popular libraries, especially back in the day, like Jake weary or even backbone Js, the idea was using this pattern. We can place all library code inside of local scope to avoid any nay space collisions. So let's have a look one by one. The first thing we're doing is we're saying with this brackets. Hey, this isn't a function declaration. It's a function expression, right, because the JavaScript engine won't see function as the first item on the line. Instead, it's going to see these brackets, so this automatically makes it into a function expression. And then after we've done that, we've created an anonymous function. There's no name, a dash to this function, and then we immediately invoke it. That is, we call the function. So if I run this well, I get undefined. Okay? But just to test our assumption, What if I do something like this? What if I use a function declaration and call it immediately afterwards? So that's our function declaration. And then right afterwards, I'm going to call it. I'm going to get a syntax air. You can't really call a function declaration immediately afterward. A function expression, however you can. Now, what's the benefit in doing this? You see, since the anonymous function within this, if he is a function expression and it's not being assigned to any global variables, no global property is really being created, is there? And all of the properties created inside over here are going to be scoped inside here. So it's on Lee going to be available inside this if he were not outside. If I have a variable A, he goes to one. Well, I can't really access. A A is not defined. Let's have a look at a diagram and immediately invoked function expression simply allows us to call immediately. As JavaScript is executing, it's going to define what it is, and right afterwards with the brackets, it's going to call it. It's going to create a new variable environment, a new execution context that's going to have our own variable scope. And this allows us to attach private data right in here that can be accessed by the global execution contact because, well, the chain runs downward. Now, Before I get into an example, let me just show you one other thing. What do you think happens if I remove or move thes brackets to inside over here? Will anything change? No, it doesn't. We're still following the rules of JavaScript, right? We have the function expression because of the parentheses, and then right after the compiler looks through the code and says, All right, here's the function. Were immediately going to run it. Let's see this in action. Imagine I create another function here. I'm gonna call it function a another original name. And this function A is just going to return five. If I refresh dysfunction and I do A I get five, that makes sense. But then all of a sudden, this little bugger over here decides to pollute my name space and create its own function A that mocks me and just last me so that now if I refresh and run a oh, boy, just laughing at me, ready, killing me. So how can we use if he's to solve this problem? And this is how we worked back in the day before we had es modules again. Something we're going to discuss in our modules section of the course. I can create a variable, Let's go and script one. And this script one is going to equal function A. Or we can even leave out the name if we wanted to. And within this function, because this is a function expression, I can wrap it in brackets and then immediately invoked. So let's see what happens now. I'm going to save and refresh if I call a I get Ha ha ha! Okay, nothing's changed. Instead of returning five. I'm going to create my function again. Function A and this function A groups must make sure we fix that. This function a well now have returned five. And all we need to do is just return from here on object with a as the function so that if I save here and refresh, let's say I Ron a again. Well, I get Ha ha ha! But now within my script one dot a I can run this and look at that. I have access to a because script one now returns an object that contains this a function for me. Now the interesting thing with this Is that what we still have a global name space We still created this script one global variable But the good thing is that we can just have one variable and this variable can be an object that contains many properties that we might wanna use And it on Lee pollutes the global name space once More importantly, we're attaching this private data toe a function that creates fresh environments for us. It executes them and it only allows us to return whatever we want from inside this function . Now libraries like J. Cree used to do this a lot. For example, let's clear this and add a J Quarry library of the very top of our file here. This is a Jake recode right at the top, so that now we'll have access to the Jake Rare Library. This means that anything that comes after the script well, because everything gets combined in the script tags, we can use J Career now. So let's do that. Let's have a function that lets say, instead of this function, a will do the J quarry syntax to grab H one, which is Theis. Hello over here and we'll just say on Click, we want to run a Kobach function that simply, well, let's say hides the hello So I can do this here if I want, but that's a topic we're gonna get into a little bit late on. So let's just stick with H one dot hide and see what happens here. And for now, let's just not return anything. Just an empty object. I'm going to refresh if I click here. Hey, look at that. It's working. It disappeared. We have access to this dollar sign because J coury provides for us the ability to use this from its library because it's added it to the window object. If I go to window dot dollar sign there, we have something here I can also do window dot j coury and again, Same thing. Now J cree inside of this library has a donna functions aton of variables. But inside it they can just create an F e and just exposed for us this Jake Riri object that we can use. So let's play with something here If in this parentheses remember, this is us executing this function. If I add Jake worry here here after we call this function, this function is going to receive this j career parameter and will make this Jake We're parameter OMG that says OMG well, this just still work right this OMG syntax If I refresh, let's save and refresh and I click here still disappears because what I've done is I've added Jake weary from the global name space as a parameter onto my immediately invoked function and this function when it gets called, it's going to receive a parameter which is Jake Riri and we're just assigning it a variable OMG But this OMG still has whatever this library gave us, so I can use it whatever way I want inside here. Now, the interesting thing here is that we actually have a bit of a performance benefit here because before we didn't have this when we looked at the dollar sign, we would go up the scope chain to the global name space and find the dollar sign and what it means. But this time around, because we've added our J career library as a parameter, it doesn't look in the global nay space right. Instead, it looks at its local scope, which includes the parameter that we had. So we technically get a bit of a speed boost because we're not doing that scope chain. Look up. As a matter of fact, we can do something fun here. Let's change this back to the dollar sign and now return the dollar sign to just equal high . If I do this and I refresh and I Ron script one dot dollar sign you see that within this function within this script, we've all over written whatever the dollar sign wants. And it's just high, completely useless to us. Immediately invoked function. Expressions are something we're going to get into and a little bit more when we talk about modules. But wanna introduce them to you now because, as you can see, they take advantage of what we learned about scope. It enables us to attach private data to a function, and it creates a fresh environment for us so that we don't pollute our global execution context. As we start to get more and more JavaScript files, we want to make sure that we can wrap things in a function to scope things into their own environments and minimize the amount of data that we place on the global execution context . I'll see in the next one, but by 37. 17 this mio: welcome back. The scariest part off JavaScript. This some would say the most confusing. Some even hated so much that they try to avoid it at all cost in their coat because it creates so much confusion. Let's try and decode this mystery and figure out what this is all about. Now, keep in mind this is a topic we're going to really dive deep into during the object oriented programming section of the course. But we're focusing on learning the fundamentals of this keyword in this section so that when this term comes up later on in the course, we have our foundation ready. So what is this? And although it looks intimidating, this isn't that hard, because all that it means is this. This is the object that the function is a property off. That's it. So what does that mean? Well, this is the object that the function is a property up simply means that we have an object and this object has some function. And inside of this function, when we do something, we have access to the this keyword, and this refers to the object that the function is a property off still confused by this. Let's look at an example if I just simply run this here if I click Run. Well, this environment won't let me work with this because of some safeguards in place. So let's one up. Our developer council and in here type in this. And if I hit enter. I have the window object. That's what this is referring to. Because remember, this gets set in our execution context as window initially. Right? Remember our diagram. When the global execution context starts during the creation face, we create the global object and this and they equal each other. In this case, the window object is our global object. So what if we do something like here? Where have function? A that well, just console log this. If I run a what do you think the answer will be? Well, we get window once again. This is equal to window. And why is that? Remember the definition. This is the object that the function is a property off. That means we're calling window dot a and running it. That's what we're doing up here. So what is the object that the function is a property off? Well, the function is a property off the window object. So that's what this is. It's the window, and this should make sense, right? But here's the problem. When it comes to coding, this part of JavaScript is a little bit weird in the sense that most of the time when we're coding, we never want this to refer to the global object. But obviously this happens all the time. And as we'll see later on, one of the pitfalls with this is that we unexpectedly have this referred to the window object when we think it should be something else. And if we go back to our example and create function, beat this time and with function be if I use use strict here and I console dot log this well, if I Ron be here, I'll get undefined. I remember what I said about the use. Strict tag. You strict was added to JavaScript as a way for us to avoid the common mistakes that can happen with JavaScript. When the language was originally designed, it wasn't perfect and there were bits and pieces off mistake and things like you strict allow us to not have this where this were first to the window object and you strict can be added at the beginning, the first line of a function or the beginning of our script. Now I know you're still confused about this, so let's give a better example. Remember our global execution context? We get this out of the box, but also when we have a new function, we have this as well. But what's the point of it, then? If most of the time we don't even care that this points to the global object, why did they even include this in the language? Well, let's let have a look at an example where this actually becomes useful and the reason that this keyword was created. Let's create an object here, and this object will have a name that is Belly and Billy can sink. So we'll have a function here and inside of this function we can just return Billy singing la la la And we wanted to say la, la, la billy, or use the name property. But how can we do that inside of an object? How can we access a property so that this sink function can sing Billy's name? I mean, we could write Billy like this. But what if this object changes and all of a sudden it becomes Veronica? Now we have to also come over here and change this to Veronica instead. We can use that this key work, I can simply say this dot name. And why is that? Because remember our definition. This is the object that the function is a property off. This is the object that these sink function is a property of. So we're simply saying here, object dot name. But obviously object dot name wouldn't work in here. So we have to have something else like the this keyword so that if I run object dot sing and I click Run here. Look at that. I have La Jolla Veronica. And if I change this back to Billy, I don't have to change anything in the function. It gives me the correct sink function, and by the way, we can actually convert this to a newer syntax. Write it like this, which also works, and it's a little bit cleaner, so let's go back to that function. This is the object that the function is a property off and this is the rule of thumb that I like to use. This refers to whatever is to the left off the dot Remember, with an object. We access properties and methods oven object and a method of an object is a function. So methods are functions that are inside of objects, so the property and methods can be accessed with this dot notation. And when it comes to this, this simply refers to hey inside of this function. What's to the left of the dot Well, object. And that's all you really need to know about this. It's whatever to the left off the dot, which is the object that the function is a property off. Now I know you're still confused. I still don't get why this is that useful. Let's use another example. Let's say that in this object I want to create another function that says Sing again and sing again And let's make this a little bit bigger. There you go. Sing again should well sing again. We want to run this function or perhaps sing again. Does something a little bit different. Maybe it adds an exclamation mark at the end. How we go about doing this? Well, I can just copy whatever the function does here and just add on exclamation mark at the end so that when I run, sing again and I click Run! Oh, and I have to make sure I add a comma here. Let's click. Run! I have sing again with the exclamation mark. But this isn't good, right? One of the principles of being a good programmer is dry. Do not repeat yourself. And this is a simple example with, well, one line of code when it comes to a function. But you see here that we're just copying coat the exact same thing over and over. A better way of doing this is to call the same function and then add the exclamation mark to it. Once again, if we change something, let's say we change something in the sink function. We don't have to change it here as well. So what we would do in this case, as you may have guessed, is this dot sink, which returns this piece of strength and then add the exclamation mark at the end. Fact like run. Look at that. It still works. We're not repeating ourselves. We're keeping things dry. That's very good here are the two main benefits of this and why the this keyword was created. The number one reason it gives us methods or it gives methods access to their object. It gives sing access to the object so that it can use properties and methods within that object. So it's siblings. The second reason that the this keyword is so important or it benefits us is that we can execute the same code for multiple objects. What does this one? Meat number one that makes sense. We have access now to all these methods and properties on our object, which is great, and we can keep our code dry like I've shown you here. But what about this second part? Well, let's talk about this second part or the second benefit of this with another example. Let's create a function and dysfunction will be, let's say, important person and this important person function simply. Console dot logs this dot name. Now if I run this, this is going to refer to the window object because when I call important or I can't spell important person important person and I run this, it's being called with the global object window dot important person to the left off the dot is the window, so this is going to refer to window. It's like doing window dot name and window dot name warm really know and you think about this. So let's create that property. I'm going to create a name property that is sunny and I'm also going to create two objects . The first object we'll have name Cassie, and we're also going tohave the important person function from up over here that's going to say important person. And then the second object we'll have the same thing will have object to name is going to be Jacob and they're going to use important person now. Right over here, I'm demonstrating the second important to use when it comes to the this key work it executes same code for multiple objects. I've written a function once and now multiple objects can use this object. One has important person method, an object to has important person method once again. And as long as I just changed the code on Lee here, both of them are going to get the changes. If I add an exclamation mark here. Both of these have the same coat again, keeping our code dry. But let's see what happens now. Let's say that I console log here and let's test this out. If I console log name here, what would the result be? Or more importantly, if I do import and person and I run this function, what do you think I'll get? Who's the important person here? Remember, the important person function simply runs Consul lock this dot name. The important person in this case is what's to the left or who's calling in poor person while the global object window is calling person. So we get sunny because sunny is the property on the global object which we created. Remember, this is a global variable. But what if I do object? One dot important person? Who's the important person? Well, who's calling it object? One is calling important person the left off the DOT. So the important person in this case is Cassie because we're calling this method, and this is now referring to. This is a function that is a method off object one. And if I change this to object to, I get Jacob. How cool is that? Those are the two main benefits off this. It gives methods access to their object, and it also executes same code for multiple objects. Both things, making our code cleaner simpler, were not repeating ourselves. So to review this is usually determined by asking Hey, execution context. What called the function? What called me? So you can think of this as who called me? Who is that person that run me as a function? And the This keyword acts as a placeholder and will refer to whichever object called that method. Now there's an interesting thing that happened here, which we're gonna visit in the next video. I'll see you in that one, but by 38. 18 this part 2 mio: Let's do a bit of an exercise. I have a piece of code here and as you can see, I have variable A. That is a function. And inside of that function we have another variable cause to be. That is also a function that we run at the end, the B function and then inside of that we also have a C function. But this time around, see is an object that has property Hi, which is a function, and at the end we're calling si dot high. Just to clear this up, I'm going to add a here in the console log. I want to add B in the console log and then finally see in the console log. Now, when I run this function, it's going to execute this piece of code which executes, goes through all the steps and executes be which will execute this piece of code, and this be will finish off with executing si dot high hit pause and think about what's going to happen because in just a few seconds we're gonna find out. Let's see. Is that what you expected? Let's see what happened here. A equals to the window object or the This keyword here refers to window, and that makes sense, right? We called a who called a while the window object called a great. What about Vida, who called B? It's nested inside the A function. Maybe you thought that we would have something else as B, but that's not really the case, right? Remember, all we did was we called the A function and the A function executed. This piece of coat and the B function well, who called the B function. There's nothing to the left. Oh, the beat, right? There's no other object that called beat show in this case, what's to the left of the dot? Well, nothing has changed into this. Keyword who called me is still window because we have window dot a function that got called and inside off year we called the B function, but to the left of the dot, it's still the window object. Now, when we get to see, that's when the interesting thing happens, because we have an object and that should trigger something for us. A. Soon as we have an object, we now see that see dot high got cold. So when we call high. What's the this keyword? Well, hi was called right here and who called High Well ceded. So the vis keyword or who called me is the high or the sea object, And this is unlike anything we've seen before. Remember when I told you about lexical scope, lexical environment? How the compiler new right away without running any piece of code. What variables functions have access to it almost looks like lexical scope doesn't work with this. It doesn't really matter where we write it in the piece of code, right? All that matters is how it gets called during in vocation. Who calls it? It matters how the function was called Let me show you another interesting example. Let's say we have an object and this object we'll have name once again. And Billy's gonna make an appearance once again, and Billy is going to you sink and here we'll just do console log, got or a consul log this nothing new here. We've seen this before, but let's add something new to this and one of the biggest gotchas when it comes to this cured. If in here I create another variable and this variable will be another function that will be function. And in here we'll have console dot Log this and just for clarity, I just say be for this one and a for this one. And the sink function will actually, at the very end, call the another function. What do you think will happen here? Now again? The rebel over here has some safeguards in place, so it actually won't let us run this properly. So I'm going to copy this and open up the console. Let's refresh copy and based here now, when I create this object and I now Ron object dot Sing Let's see what happens. Is that what you expected? I have a So the value of this referring to the object that had Billy and the sink function That makes a lot of sense. But what about this one? What just happened here? This doesn't make sense at all, right? I mean, isn't this inside off the object over here? Why is this referring to the window object? And this is like I said, one of the biggest gouaches when it comes to that this key work because the this keyword is not lexical e scoped. That is it doesn't matter where it is written. It matters how the function was called. What actually happened underneath the hood is that object dot sing ran in this object dot sing inside of the sink function. That's where another function got rent. Object didn't really call another function the sink function did in JavaScript. This key ward defaults to the window object in here. I know it's extremely confusing, right, and this created a lot of problems for people because this air was so common. Remember this in JavaScript are lexical scope that is available data. Variables. Where the function was defined determines are available variables, not where the function is called, which is called dynamic scoping. But there's actually a little footnote to the state, right, because everything in JavaScript is actually lexical e scoped. How we write it determines what we have available. Except for this keyword. The this keyword is actually dynamically scoped, that is, it doesn't matter where it's written. It matters how the function was called. So how do we fix this problem? How could we avoid this pitfall that a lot of people had had in the past? Well, there's two ways to do this. Let's have a look If I copy this back and let's just refresh here, I can solve this issue using what we got in E s six arrow functions. And you may have heard the term arrow functions are lexical lee bound. That is a refund. Shins has a lexical this behavior unlike normal functions. So if I change this function to an arrow function instead, it's going to lexical Lee bind. This, that is Hey, what object is surrounding this while the main object is so by just doing this? If I run this se sink Hey, look at that Problem solved. Not too bad, right? And that's what aero functions gave us, which was amazing. It prevents a lot of this confusion, and this is something we're going to talk more about in the object oriented programming section. But what do we do? Before we had es sex and air functions another way that we were able to do this before we had a row functions was to do something like this where I return another function and I bind to this which, because we're doing this line of code outside of this function, this is going to refer to the object. Let's see what happens when I do that, and I have to refresh. Let's try that again. And if I do object dot sing. But then object dot sing actually returns another function. So if I do object dot sing, call the function and then call the function again, which will be running this line of code I get. Look at that. Both this keywords are now part of the object. Now, I know that's really confusing. I just wanted to show you what we did to solve this issue before we had a row functions. But what does bind really do? Well, in the next video, we're gonna find out. I just remembered that there is one more way of solving this issue. The issue of this keyword in here inside of another function being the window object. And this is something that you may have seen a lot, especially if you've worked in the past with Jake weary or the first version of angular, where in order for us to capture the this value and in order to have a referencing the object, what we would do is outside of the function itself create a reference so that, for example, variable self is equal to this. And because of the time this line is run, this is still inside of the object. We're going to maintain that reference to the object so that here we can use self inside of the another function so that if I run this function, I see that both the sing function has a reference to this which is the object. And also the another function has the reference to the object using the self variable. 39. 19 call() apply() bind() mio: welcome back. In order for us to manipulate the this keyword, there are three really important methods that you see a lot especially for senior JavaScript developer interviews that is call, apply and bind. And we saw bind in the previous video. So let's talk about them and see how they can be used. The first thing we're gonna talk about is actually calling apply. And they look a lot more intimidating than they actually are. Because underneath the hood, all functions use call when invoking a function. Let me show you what I mean. If I do function a here and inside of here, I console dialogue. Hi. If I do a dot call and I run this, I get hi underneath the hood in JavaScript when I do a bracket bracket to invoke the function, all functions when created have this property called coal that allows us to call the function. So this is just a whole shorthand that we can use. How cool is that? What if we do apply here? If I run this same thing Colon apply Do the same thing for now at least. But let's see how call and apply can be useful Besides just calling functions, let's say that we're creating a game and this game has a wizard. Obviously all games do, and this wizard has a name off Merlin, obviously, and Merlin has a health of 100. Go for Merlin. He's nice and health, and obviously because Merlin is a wizard, he has a hill function. And this hell function can make this dot health again. We're referring to a property of an object to Eagle 100. That's an awesome power. So that any time I do wizard dot hell, well, let's return something here so we can actually see what's happening. I get ah, 100. That's fantastic. If his health coast to 50 Well, as long as we run, he'll we're all good. It's still going to be 100. Okay, but in the game we need more than just one character, right? Let's add another character. And this time around, I'm going to odd ad on Archer. And this archer name will be well, Robin had obviously and health for Robin Hood is on Lee, 30. I know he's not doing too well. He needs he needs some healing power. We just created this piece of code and Robin Hood doesn't really do much, has a name and health. But would it be nice if we're able to borrow a function from the Wizard and he'll archer? And I know I'm using a silly example here, especially for an advanced course, but I hope you can see the power of being able to borrow methods off other objects so that we keep our code dried right. We don't repeat ourself. We don't add to memory. We have one place where the method is in one place where we can change it. This is going to create a lot less bucks in our coat. So how can we borrow the hell method for the archer? It's not part of the same object, so we can just use this dot Hell, right. We can't really just do this start hell, because while this object doesn't have it and we don't want to copy and paste the coat instead, we can borrow it and we can use coal and apply to borrow methods. So let's see how we can do that. I can simply say wizard dot hell, So that is the method I wanna use. And instead of calling it like we have before I use dot call, which, if I run this, I'll just get Wizards health. But in here, I'm going to use call, and then the first parameter off call will be what this should be bound to. And if I scroll over here, you can see that call calls a method of an object substituting another object from the current object. Very, very confusing. But essentially, it's saying, hey, call hell instead of using wizard to call hell. Use Archer to call hell. And we're just gonna borrow this hell from the wizard so that if I run this well, we don't know what happens yet, but let's just consul dot log archer and console lot log Hartzler again. So this is one and this is to if I run this. Did you see that at the beginning? My archer only had health of 30. But after we used Merlin's, he'll power and used it on Archer. Our health went back up to 100. How cool is that? And coal actually has other parameters that it can receive. It can receive arguments so that we can give Archer or the hell method parameters so For example, let's say the hell method took number one and number two, and what this does is well, we add number one plus number to so whatever two numbers would give it adds to our current health. Let's make this a little bit bigger there. You on this a lot cleaner. I can now call Archer with the parameters. So what are the parameters going to be? I'm going to give Archer 50 Health plus less, too 30 help so that if I run this I have 110 now because to my current 30 health, I've added 50 which is 80 and then 30 which is 100 10. Look at that 110 health. That's pretty good. That's all Coal is really useful for. I mean, it is quite useful, isn't it? And when it comes to apply, like I said, it does he same thing. The Onley difference between call and apply is that instead of call that just takes parameters, parameters, parameters with apply, it takes an array of parameters so that if I do this, it's still going to work. If I change this to, let's say, 100 look at that 160 health. That's pretty cool. So choosing which one to use, call or apply just depends on which one is easier to pass, He arguments and just decide whether it's easier to pass array off parameters or comma separated list of arguments. So next time you're thinking I'm really jealous of that object than method that that object has wouldn't be nice if I could just copy it well, does that function include that this keyword so that it could be dynamic cool? Then you can use call or apply on it. That's your test. All right, that's enough for Colon apply. But what about the other one that I was talking about? Bind. What happens if I use mind well similar to call and apply? Bind allows us to use what we have here. You see buying. Unlike Colin, apply that immediately runs a function Bind returns a new function with a certain context and parameters, and it's usually used when we want a function to be called later on with a certain type of context or a certain type of this keyword, let's see how that would work. In order to use bind, we would do, bind and find. Except so just like call parameters. But if I run this now, it doesn't work. My archer Robin Hood didn't get healed. And that's because, unlike call and apply, it doesn't run the function. It returns a function so that if I added to a variable, let's say Hell Parcher so that we can use this function later on. We can now run. He'll departure. And if we click, run, Look at that are Archer is healed. So bind allows us to store the this keyword or this function borrowing for later use. And you might have noticed something here. Bind is like a Band Aid to fix this idea of a dynamically scoped this keyword that ruins our entire lexical scoping discussion that we've had remember in the previous video how we talked about this solution when we didn't have the arrow function we can use bind. I hope that makes sense. Now we are able to store the value of this which was object so that we can use it later so that another function, instead of giving us this weird, dynamically scoped this keyword, were able to bind another function to use the this key word that is the object, so to review, called and apply. When are they useful? We'll call in reply. Are useful for borrowing methods from an object, while bind is useful for us to call functions later on with a certain context or CERN this keyword. And by the way, there's one more interesting use of bunt. Let's explore that in the next video. 40. 20 bind() and currying mio: Welcome back. We learned how weaken, do function, borrowing with apply and call. And we also learned how we can use bind to do the same thing and also called a function later on when we want with a certain value to the this key work. But there's one other useful trick that you can use with bind. And it's called function currying something that we're gonna learn a lot more about in our functional programming section of the course. But you can do something interesting with the bind method. Let's say I had a function and this function was called Multiply, and it's simply multiplies to numbers. So we just returned a Times B nice and simple. Now currying refers to, well, Onley, partially giving a function a parameter. Now, why would this be useful? Why would multiply to be more useful than just completing the entire parameter list? Well, because we can do something like this, we can have, let's say, a new variable multiply by to, and this is going to use the multiply function, and I'm going to use bind the method here that's going to bind to this. And what is this? Well, it's the window object. We don't really care because what we care about is giving the parameter to the multiply. So this is just an unintended consequence of using bind. We don't really care. So we're just gonna leave it at this the window object. But now if I give it to here and I hit enter well now I can run console dot log, multiply by two. And if I run this well, it's a function it's returning for us, a function that we can use later on. But it already has one of the parameters in it, so that if I run, multiply by two, let's say multiplied by two. Number four, which will be the second parameter, and I run this I get eight. How cool is that? I created a new function called Multiply by two that multiplies anything by two. By giving it the first parameter to be to so that I can keep doing this right, I can create another function. Let's say multiply by 10 and this gets a parameter of 10 so that when I multiplied by 10 I get 40. How cool is that? This is something that we're gonna learn a little bit more when we get into occurring videos. But I was able to re use a piece of code, give it a partial parameter and create these functions that are extensible that are more specific, such as multiply by two or multiply by 10. I hope this gets you as excited as it gets me. I think it's really, really cool and an interesting concept of bite. All right. I want a little bit of a tangent here, but I'll see you for some exercises in the next video. 41. 21 exercise this mio: Welcome back. Let's do a nice little exercise to solidify our knowledge of the this keyword I have here three objects and each one of them has a name and a say method that are slightly different . What do you think that this values or what do you think the log will be on the right hand side here? Let's start off with the 1st 1 If I do b dot se What's going to happen? What will this be if I run this? Did you get that right? This should make sense, right? This is the object. Be nice and easy. Okay. What about C? This time around, we're returning a function, so this might look a little bit confusing, but we're essentially saying the safe function is going to return another function. So that's a function inside off another function and that's going to return. Consul, log this If I run this or I should change that to see if I run this, I get a function that should make sense right when we run, say it returns for us this function. So if I run this function again by doing this, what's going to happen? Who calls this function. This gets called first, and then this gets called. Let's find out. Oops. I get an air again. Remember, Code sandboxes like this sometimes give out an air because this is an unexpected use of this. So this part we have to copy and open it up in our consul by copy and paste year. And I run this I get the window object because, well, remember, a method that has a function inside of it, that this gets bound to window an unintended consequence off JavaScript off dynamically scoped. This that was the tricky one. Let's refresh here. What about D object D that uses an arrow function this time around instead off just the function. So this is going to be lexical e scoped. If I run this well, I get a function. Nothing new, right, because we return a function. But if I call this function again and I run this Hey, look at that. It fixed our problem because that this keyword was lexical Lee scoped inside of the air function. It doesn't care about where it was called 42. 22 Context vs Scope mio: Welcome back. I wanted to have a quick video to clarify a term here, and that is context vs scope. Scope is a function based. Think right scope means what is the variable access of a function when it is invoked? What is in the variable environment? Right? Context, on the other hand, is more about object based context, says what's the value off this key word, which is a reference to the object that owns that current executing coat. So contexts and scope is something that people get confused between. And especially when we start talking about context, execution as well, it gets a little bit confusing. But just keep this in mind. Context is most often determined by how a function is invoked with the value of this. Keyword and scope refers to the visibility off variables. All right, I'll see in the next one. But by 43. 23 Conclusion mio: holy moly. Finally done with the foundations. We're gonna get to some exciting parts. But what have we learned so far? Well, we learned how the JavaScript engine and the compilers and how a language is red and execute her right. And then once a language like Javascript is executed, we learned about execution context. How every function in vocation creates an execution context. We learned about lexical environment. Where we write our code is important. We learned about the scope chain, a way for us to look for variables and see what we have access to. We learned about an interesting feature that is hoisting how javascript does this weird thing that hoists function declarations and variable declarations. You learned about function in vocation and some of the interesting properties. When we create new functions such as getting the arguments parameter, or sometimes even modifying the this keyword we learned about function, scope and block scope and how in javascript Originally we only had function scope, but with the new let and constant key words, we can use some block scoping. We learned about dynamic and lexical scope, how javascript just has lexical scope, except for this little thing called the this key work that has dynamic scoping that is it gets determined what this value is when the function is invoked. We also learned how to master the this keyword the benefits off, having the this keyword how to use call, apply am bind. And we also learned about immediately invoked function expressions. Now, especially these two this and the if he's is something we're gonna talk about later on in the course. So we just scratched the surface with these things. But by now, you should have the foundations of JavaScript done. And we learned some really complex topics that really make you a great programmer. I hope you are having fun. I know that was a tough, big section, but trust me, things they're going to get better and better. And as we progress through the course, you'll see how the foundations that we've laid out are gonna help you expand and learn and become better and better as we progress through the course. So don't give up just yet because we have lots more to go through. I'll see in the next one. Bye bye. 44. 01 Introduction3 mio: welcome back and good job getting this far in the course where in this part a tiny little part before we get into the two pillars of JavaScript. A really, really fun topic that I'm excited about. But first we have to get through this part. Now all programming languages have types. That is the building blocks that allow us to write in that language. We can have numbers, strings, bowl Ian's and many more. And in programming there, two types of languages dynamically and statically typed languages. In this short section, we're gonna be talking all about types and the idea of types We're gonna define what static vs dynamically typed meats. We're gonna talk about primitive types passed by reference versus passed by value. We're gonna talk about a very confusing topic in JavaScript type chords, and we're also gonna talk a little bit about arrays, functions and objects and how they relate into this whole ecosystem off types in JavaScript . This is an important stepping stone in order for us to master the language. So let's dive in and gain some new knowledge. I'll see in the next one. But my 45. 02 Primitive Types mio: Welcome back. Let's talk about the different types that we have in JavaScript. And luckily for us, there aren't that many. There's only seven of them. We have numbers like five. We have Bull Ian's like true, false. We have strings like to be or not to be. We have undefined, which we've talked about. We also have something called No, we have another special one that came with Yes, six, which is a symbol. And in here for now, let's just say just me. And then finally we have objects. 1234567 And you're looking at the list and thinking, um, Andre, I think you missed a bunch of others. Were are a raise or functions well before I get into that. Luckily for us, JavaScript has an operator called Type of That tells us the type off an item. So let me comment this out and find out what the type of five days It's a number. All right? That makes sense. What about type of truth? I run this its bullion All right. So far so good. Nice and easy. What if I do type off? To be or not to be That's a string. Easy peasy. What about type off on defined? Well, that's undefined. It's a special value. And JavaScript on to find What about type off? No. Whoa, what just happened here? Knoll is an object. What? This is something that we're gonna talk about a little bit more women get into the object oriented programming part of the course. But this is actually a mistake. I'm not making this up. It's true. Even the creator of the language, Brendan Eich, who created JavaScript, acknowledged it. Remember, No programming languages. Perfect. We all right programs that well can never be buck free. And this is one of those cases that, Hey, this should be no right. It's an actual type in JavaScript. It's a what we call a primitive type. But when we run the type of no operator, we get object. There was actually a proposal to fix this, but because there's so much legacy code that depends on this type of no being object that while they couldn't really change it, because it will break a lot of programs. So for now we're stuck with that and trust me, there's a lot more. We're things like that in JavaScript. So let's get over to the next one. Let's look into type of symbol. If I had run. It's a symbol. No, a symbol, like I said, is new in E. S six, and it creates something unique for us that is a symbol value in this case, just me is useful for identifying an object. So symbols air usually used for object properties so that the objects property is unique. We're not going to concern ourselves too much with this. You can read up on it if you want, but it's just a new type that we have that allow us to do some interesting things with object properties. All right, last one type off. Actually, before we get to type of Let's go back here undefined and no, what are the differences between the two? Well, undefined is the absence of a definition, so it's used as the default value when the JavaScript engine initialize is our variables, right? Remember our talk about hoisting well, we use undefined for anything like that, or even cases where let's say functions return undefined. When they don't return anything, there's no return keyword in a function, or there's missing properties of an object undefined simply means well. There's variable there, but there's nothing there. No, on the other hand, is the absence off value. It means there's no value there. I know the distinctions a little bit. Hard to get. Remember, undefined is the absence of definition. No, is an absence of value. There is no value there. And this is something will get into a little bit later on in the course right where we docked two objects. If I do type off here and I hit run, it's an object. Nice. That makes sense. Okay, so where the race? Let's have a look. If I do type off array, that's a knob checked. Okay, What about type off? Let's say a function like this. If I run this, that's a function. Whoa. So, Andre, did you just teach us something completely wrong? There's clearly a type of function in javascript, right? Well, technically, no. And for now, I need you to trust me on something. I need you to trust me that this diagram makes sense. That is a raise and a functions are objects. That's something that we're going to get back into later on in the course, and we're really going to define what this meets. But for now, just remember, functions in a race are objects. And even though type of function gives us a function underneath the hood, a function in JavaScript is just on object, all right. Still, don't trust me. What if I just do something like this fight? Comment out this code and I create a function function a. And in here I'll say return. Five. The simple function. But now can I do something like this? Can I add a property to a function just like I can with an object with the DOT notation? If what I told you is correct and functions are just simply object, This should make sensory. This should work well, let's find out. Let's console dot log a dot high If I run this all right, it's working. So this is something will come back to you, but for now, the least, maybe 80%. You're convinced that functions are objects, but let's get back to what we're talking about. We have the type of operator here that tells us what type something is. And in Javascript we have two distinctions. We have the primitive types which are right over here. And then we have the non primitive types. Now what's the difference between the two in JavaScript? All types other than the object type are all primitives. So what is a primitive type? It's a data that Onley represents a single value, so that means this primitive five well in memory. The value is five in memory. The value is true in memory. The value is this piece of string undefined knoll symbol. There's no ambiguity about it. A variable over your primitive type directly contains the value off that type. Think of it this way. They're kind of like Adams, where they can't really be broken down into any smaller parts. Five is just five, and memory no is just know. And memory symbol. Just me is just a symbol that has just me in memory. A non primitive type doesn't contain the actual value directly. What does that mean? Well, if I do something like an object that equals, let's say on object that has property a equal to Tom, this object doesn't actually contain the value here directly. Instead, it has a reference similar to a pointer to somewhere in memory that the object is health. Now, I know that's still a little bit hard to grasp, and we're gonna have a video coming up on passed by reference versus pass by value where we discuss the difference here a little bit more. But before we get into that video, I want to finish off with one last thing. That is the idea of JavaScript built in objects and you can see some of the built in objects here. Now, when I say built in objects, I don't mean global objects like we saw when we added things to the window object. No standard built in objects. Come with the language. It's part off the language. And if I scroll through here, we see some familiar ones like infinity, not a number on to find. If we keep scrolling, we see error. We see symbol, we see number, math date, and I'll link to this mdn page so you can take a look for yourself. These air built in objects that come with javascript. But you might be asking yourself, Why do we have things like well, bullion? Why do we have things like number? What do we have things like strength. Didn't we just say that those are primitives? Those aren't objects, right? Well, you may have heard the term. Everything in Javascript is an object. And bear with me. Here, this gets a little tricky. Many things that we interact with directly in javascript, such as strings, numbers, M bullion which are primitive and not objects get a little bit complicated by the fact that these primitives have object rappers like strength four number four bullying. Let me demonstrate for you what these do. For example, if I do true here and I due to strength and I run this I get true in string for Why is that ? This is a primitive type. Why is it acting like an object By using dot notation and doing to strength? You see, this is where Javascript gets a little sneaky. It silently creates a rapper object around this truth something like this, when we try an attempt to access a property on a primitive so behind the scenes is almost like it's wrapping this in bullion so that it has access to to string and then finally returns. True, super confusing. I know. So keep in mind that things like Boolean or let's say String, for example, exist in order in order for us to be able to use some methods on these primitive values. So no, not everything in JavaScript is an object. But there are a lot off object or built in objects that we can use so that if we do type of math, for example, that's a knob checked. If we do type of infinite in JavaScript, that's a number like I said, types and JavaScript can get a little bit tricky, and most of the time you don't really need to concern yourself with the inner workings of these things. Try not to confuse yourself too much with it, but I think we still need to work on this idea. Off objects, primitive types are simple types, like number strings, brilliance, right but objects. Those are still a little bit confusing. So in the next video, let's work a little bit more on this 46. 03 Arrays: Welcome back. Let's do a quick video on a race. Remember what I said? A. Raise our objects in JavaScript because underneath the hood, if we do, let's say an array that contains 123 and JavaScript. It's almost the same as saying variable object. Or, in this case, array equals index of zero. Contains one index of one contains two and index of two contains three. If I change these two strings, that would be the same thing is this And that is why, when we do type of and check out an array, I get an object. Now, how will we ever test to see if something we create is Honore? Let's say we create a variable somewhere and we want to find out what this variable is. Does it contain an array and object? How could we figure out if type off array is the same thing as type of object? Well, in the new version of JavaScript, we actually have something called array. Dot is a rape, and this array, as you can see, is an object. It's an array constructor, which we're gonna talk about a little bit later on in the course and we use the don notation to access a new property or method on it is rape. And in here we can give it something to see if something isn't right. If I give it an array, it's going to run true. If I give it, let's say on object is going to give me false And that's how we check for a race and JavaScript. Otherwise, it'll be really hard to determine if something is in a rape and job, because once again, a raise in JavaScript are objects I'll see in the next one. But why? 47. 04 Pass By Reference vs Pass by Value mio: Welcome back. Let's talk about past by reference versus passed by value to finish our discussion about JavaScript types. Now, in the previous video, I said that primitive types are immutable. What does that mean? Well, it means that we can really change them in order to change them, we need to completely remove the primitive type. And let's say, if variable a equals five well, in order for me to change what that five value is, I have to literally move it from memory and create something new like a equals 10. I can really modify it. Just something new gets created, and primitive types are exactly like that. When I assign variable a to five somewhere in memory, variable A is going to contain and reference the value. Five. If I do very Bowlby equals two, let's say 10 again. Same thing and they don't really know off each other's existence. This is what we call pass by value. Objects, on the other hand, are what we call pass by reference. Let's write some code to figure out what this really meets. If I do variable a equals to five and then I do Variable B equals 2 10 Well, a now has an address off where this primitive value five sits in memory and same with B B has an address of where the primitive value 10 sits in memory. What if I do B A variable B equals two? A. What happens then? Remember primitive types. They're passed by value when we do pass by value. Well, what if I do something like B plus? Plus here. So that is add one to be if i console dot log A. I have five and if I console dialogue be I have six and this is because of past by value. All I did or all the JavaScript engine did was copy the primitive type value five, as if I was doing B equals five. So that now be has a reference to the value primitive type five. All we did was copy the value. So looking at this, this diagram should make sense any time. Even though we did B e goes to a we simply copied the value and put it into a new memory space in our machine. Remember our memory heap, or are stack where we store information? We just simply made a copy. They don't really have any connection whatsoever, and that's what passed by. Value meets pass by Value simply means we copy the value and we create that value somewhere else in memory. Now let's see how objects are different, unlike what we have before. Or let's keep this here for now, just so you can see if I create an object, Let's say object one and object one has name of Yeah, and let's say this is a user that also has a password with 123 as the password Super secure . I know. And we're also going to create another object let object to. And this is going to be well, we can just copy the first object, so object to an object. One should be the same, right? But what if I go ahead and with object to I change password to equal easy peasy? What will happen then? If I console dialogue, Object one. And I also console log. I object to and I run. Whoa! What just happened? Password has been changed. Both object ones Password An object twos password were updated by doing this. And this is due to pass by reference. You see objects in JavaScript are stored in memory and are passed by reference, which means that we don't copy the values like we did with primitive types. We simply when we assigned object one to object to was simply said, Hey, this is where the object is in memory. If we go back to the coat object one an object to are both pointing somewhere in memory. We don't know where somewhere in the memory heap to a shelf that contains this information . So all I did by saying object to equals object one is Hey, this is, let's say, the address in memory off wherever this is located so that what that means is when I change object dot password like this, I'm saying, Well, change password on this object in memory that also object, one is pointing to its referencing. That's where passed by reference comes from now. Why do you think that's a good idea? Let's think about this. Why is this good? I mean, it's kind of nice, right? Because by just having one object here, we're saving space and memory. We're not copying and cloning the object, creating multiple version. We can simply save memory reference just one location instead off just loading up our memory heap. But why this also be bad. Well, because, unlike a primitive type, we might have this issue where by mistake, somebody else changes a property on that referenced object. So this is something that we need to be careful. Let's do another example And just to prove like I said before that arrays are simply objects. Let's try this with an array. If I do variable see and this variable C has 12345 and then variable D is equal to see and then finally will say, d dot Push some giant number on. Make sure it's a number, not a string. If I console log, see or let's Consul log de first and I run this. I see that. Yep, we modified theory, but because a raise our objects there passed by reference sie should also have changed. Right? Fight, Consul log See? And I run. Yep. See, has also changed as well. We noticed something here rate. This is good. We're saving memory. We're not just constantly copying things. Imagine if see was a massive, massive object. If we're copying to different parts of the code every time. Well, this would create a lot of memory. But then there are times where maybe we do want to have flown an object. Copy it so that we don't modify it like this. How could we do that? Well, was something like an array. There's different ways of doing it. But I can simply do array on empty array and then do the cat method, which pushes whatever I haven't see into this empty array, so that when I run here, you see that C is still the same. But if I go to D, I have a new array. It's cloned on a rate. Objects are a little bit more difficult. Let's say we had an object that equals a one. Let's say B is to that's a little confusing, less to a a and then be be and then finally see, he goes to see And this object I want a copy. I wanna have this piece of code, this object in a different location and memory. How can we do that? Well, I cant do another object like this because it's simply going to pass by reference, and we're still going to be referencing the same object. Instead, we can clone on object by doing something like this object dot the sign. And in here the first parameter is the object to copy do which is an empty object. And then what is the source? So that is from which to copy the properties. So in my case will be the object So that now if I change, let's say object. Okay for LSU object C to equal five. If i console dot log the clone object and I run, I made a low Been mistake. Let's see here No knife had a semi colons instead of a comma. There you go. If I run this look at that. The cloned object was not affected at all. Even though we changed. See to be five. Remember, if we didn't do this, we don't clone it. And we just did object that would have been passed by reference and you would see the change that we saw in the original object. But because of object out, a sign were able to clone the object. Very cool. There's also another way of doing it, and that is using the spread operator Aiken do let clone to equal object or not really, we just create an object and then do dot, dot, dot and Andy object nice and clean. And this is a new feature that we got in the JavaScript language, which is really, really nice. And once again, if I run this code, I see that clone hasn't been modified. And if I do clone to that hasn't been modified either. Just for reference, I'll add the original object as well to see that indeed, it is different than what we had before. Awesome. So cloning is great, But let me ask you this. What do you think will happen with the code that we have if we have an object inside an object, for example, if C, instead of just being a strength, is another pass by reference object that, let's say, has deep as a property, and this deep is going to equal? Try and copy me. I hope that makes sense. Let me adjust the indentation here, so you see it better as to what is happening. So what happens here? We have a object that is referenced somewhere in memory, and inside of that object, there's again another pointer to another place in memory that references this object. Let's run this code. Well, nothing has changed, right? I mean, si has obviously changed and well, that's something that we already saw before. But what if I change d this time around instead of see what? If I do object dot c dot deep and deep is now going to say I don't have fun. What do you think will happen here? Let's run this code and oh, no, we've just We cloned everything, but it got overridden. I thought we cloned everything. What? What happened here? Remember, each object gets passed by reference. So although we cloned the object, the initial object, this is what we call a shallow clone. It clone the first level. So that is the memory address in this object. But within this object, there was another address to another object. So again, remember, this is just another address that we had some place in memory and this address Well, it never changed. It always referenced this object. So this is shallow cloning where we can Onley clone the first layer. That's a big problem, right? How can we do deep cloning and the way we can do this is, well, a little funky. We use Jason, we say, Let Super Club and we're going to use the Jason dot parse method. And this is beyond the scope of the course that you can read up on what Jason Parse does. But this Jason object is going to say, Jason dot string. If I Let's make this a little bit bigger, there you go. We're going to string. If I that is turned everything in here into a string and then once we turn everything into a string, we're going to parse it and turn that strength back into an object so that if I do super clone now the bottom here, let's do Super Clone and I run. Look at that. Try and copy me. Super Clone. Let's make this a little bit smaller. There you go. Super clone version Dead. A deep clone of the object. Very, very cool. Now, before I end this video, I hope pass by reference and pass by value makes sense to, you know, I do want to give you a bit over warning. However, if you're doing a deep clone, well, you should be careful because this can have some performance implications. If this object was extremely deep, a massive object, it's going to take a long time to clone everything. Right? So you won't see this out in the wild too much. If you're cloning objects like this, there's most likely some other ways that you should be doing things. But I wanted to show you the idea off, passed by reference. The idea of shallow cloning, deep cloning and some of the ways that we can use objects to get the desired up. All right. I hope that was fun. I'll see you in the next video. Don't. 48. 05 Type Coersion mio: Ah, type coercion. If there's one thing that's gonna make you pull out all your hair out of frustration, it's time Coercion. If you Googled type coercion in javascript and looked at some of the posts, you're gonna see a lot of people angry at some of the funky things that JavaScript does. And we're gonna talk about that, and I'm going to just give you a brief overview of it because it does get really convoluted complex, and it's something that you should understand and know what it is. But you don't have to know every single detail because most of the tricky parts well, you shouldn't be using it in your code because it's confusing. So what is type cordial? It's something like this. One equals two strength one, and that equals to true. You see type. Coercion means that when the operations that is the things to the left and to the right off the operator are different types, that is number and string type. One of them will be converted into an equivalent value by the JavaScript engine, so the JavaScript engine is going to say one equals two string one. I think you mean number one. So it's going to do this for us and compare number one to number one. Now, based on that definition type coercion means the language, converting a certain type to another type. Let me ask you a question. Do all languages have type coercion? What do you think? Yes, they do, because we always need to convert types between programs to do things in memory. Different types look completely different than what we type right. The number five in actual physical memory of my computer is represented in ones and zero, and all languages do this. So there is some sort of type coercion, a different levels of the stack. It just so happens that JavaScript has an especially heavy type coercion nature to it because it's dynamically type, which is why it does this. Let's go back to the example. In JavaScript type coercion happens when you used the double equal double equal sign. Simply means compare the two values, and if they have different types, try to, well, curse one into the same type. If we go back and do a string here and I do three equals and I run, I get false because three equals in JavaScript means compared to values. But don't try and curse the values. Be explicit with your comparison and do exactly what I tell you. So is there ever a time? You should just use two equals instead off three equals? Uh, I would say that No, there isn't. Some people may argue that double equal can actually have some interesting applications where we court or something, and we do some sort of checking really quickly. But it's not predictable code, right? It can be confusing. It could really be a gotcha and trick some people, so always use three equals instead of two. Now, type coercion doesn't happen just with the equal sign. You can also do an if statement. So if one then return five. And if I run this, there's no function in here. Let's do consul dialogue. I've been recording for a long day today. All right, so give me a break. Everybody all right? If I run, this five is logged. Why is that? Because javascript courses one to equal. True. What if I do zero here? If I do zero No. JavaScript courses this and says, Well, I want to bully in here, so I'm going to take your zero and turn that into a false now, this sort of tie coercion. There's a lot of interesting specifics to it, and as a matter of fact, there's a nice little website that shows you some of the comparisons that JavaScript does with three equals that is, with no type coercion. Things make sense. You see that false equals two false and that's it. You can see that string false Onley triple equals and returns true with shrink. False again. But if we do double equals well, oh, boy, that's just a mess, isn't it? For example, String one is the same as true on Array that contains one is also true when it's compared to strength of one and there so many weird little edge cases here. If you want to play around with this, go for it. But I like to stick with triple equals. You can also see some of the if statements here and some of the if cases, that can really be tricky. Now. If we go to this mdn page, which I will link Teoh in this video, we see that we have the double equals the Triple Eagles But then also something called object. Dot is that's fairly new to JavaScript, and this is an interesting one that you most likely won't see very often. But I think it's interesting. So we're gonna talk about it just quickly. You see, in JavaScript there's a concept of negative zero and plus zero Strange. I know. So if I do negative zero triple equals plus zero and I run, I get true. But they're technically different things in JavaScript, so I can actually do object. DOT is and give it the two parameters and run and I get false. Now, why is this useful? If we go back to this page, we see that object that is works pretty much the same as the triple equals. Except for a few cases, that is the plus and negative zero. And if we scroll all the way down to this funky little n a n not a number, and we can do a whole course on how weird this not a number is. But if I did not a number which represents not in numbers and JavaScript and I do triple equals, not a number, I get false. But why is that this is This should be equal, right? So if we use object, that is, this turns into truth again, most likely in your day to day programming life. You're never gonna encounter this problem. But I wanted to demonstrate for you how confusing type coercion can be. And if you're the type of person that just loves type coercion and wants to read all about it and understand all these intricacies, I link to the actual spec that talks about how the equality comparison algorithm works for me. If I read, this will be a good bedtime reading to make me fall asleep. If you're interested in it, you can have a look. The main take away from here is that well, you should use triple equals because type, coercion and JavaScript can be really tricky. By the way, as a fund little side note is a screen capture I took from Netflix watching this great hilarious documentary. And you see that bugs in the code are unavoidable. Even the mighty Netflix every once in a while has an issue somewhere, Not a number. All right, that's it for now. I see in the next one, but by 49. 01 Introduction4 mio: we finally made it to another important section in discourse. The two pillars in this section. We're going to be talking about what I think are the two of the most important concepts in JavaScript and also the most powerful. These two powers that we're gonna learn are also quite unique and not available in all languages. But it's also why it makes javascript so powerful. If you understand these two topics that we're gonna talk about that you're truly going to involve as a programmer, if you want to be considered a senior JavaScript developer, you have to know inside and out. So what are these special skills? It's right here. Closures and prototype all inheritance. If you worked with Javascript before then for sure, you've heard of these terms, but they're pretty advanced, especially if you want to deeply understand them, which we're going to do in this section. But before we dive into these two pillars, we're going to quickly talk about some of the below topics right over here. Higher order functions and functions versus objects in order to truly understand these concepts. And once we have all of that in place and we talk a little bit about the birth of JavaScript And how scheme and Java, where inspirational to Brenda night when he created JavaScript. What we're going to learn here and the two pillars is going to allow us to really move on to object oriented programming, functional programming to really start using what we've learned to make ourselves a better program. So let's get started and I'll see in the next video bye bye. 50. 02 Functions are Objects mio: Welcome back. Let's start off by talking about functions. Remember what I said? Functions and JavaScript are also object. And throughout the next couple of videos we're going to explore that. But let's review what we have learned about functions so far. When we invoke a function, we get two parameters automatically. We get the this keyword in the arguments key work, and we learned that arguments is an array like object that has some weird behaviors for looping and it aeration. So we want to avoid using it and instead use something like the spread operator. And we also learned that because of the arguments object, we can technically not have any parameters defined for a function. And when we call that function, if we add parameters to it, we can still grab them. Using the arguments keyword. We also learned that when we define our functions and the compiler looks at our coat lexical e, it determines what variables are available for us in our variable environment, and it also add our scope chains and we have a few ways of invoking and creating functions , right. The first method we're very familiar with. We have function one and this function, one is going to return one. We've defined a function and we can invoke it like this nice and easy. So that was our first way of invoking a function. Another way of invoking a function is as a method that is, a method is a function inside oven object. So if I do something like to and dysfunction to well returns to, we can call this method off the object as object dot two and run the function. I can also simplify this instead of saying function here with the new Eckman script. Six. We can just do that. So we're now calling the function as a method, and we also notice here that because the object is the one that's calling to the this keyword will also be updated to object and set off window. So that's our second way. Another way that we've learned to use functions is using the call and apply. Great. If I do return three here, I can call this function by doing three dot call and running this function. There you go. So those are three ways that we can define and invoke functions, but there's actually one more way and this one you're not going to see very often. And it might look confusing to you at first. But just to show you we can also do something like this cost for equals. Two new function and in here we say, Well, let's return four. If I run this function and click run look at that I get for this is called a function constructor. Remember our built in JavaScript objects that the Javascript language itself comes with? Well, that's what it is. It creates functions for us, and this new keyword is something we're gonna talk about in the object oriented programming section of the course. But all we do is the first parameter is whatever we want the function text to be, which is to return for. And I can also add parameters. So if I give it, let's say parameter numb and I say return numb. If I call number four with four here, I still get for it except parameters, and whatever is in the last parameter off the function will be the actual code body. But remember what I said before functions are objects, and it's something that is not very common in other languages because in Java script I could do something like function. Woo hoo that console dialogues. We who a very exciting function. But this function I can also say rue who dot yell an ad properties to it like ah, and underneath the hood. What JavaScript does is what it creates. A special type of object called a cola ble object. That is, it's this special object was just show you some pseudo code here. So it's not exactly what's happening underneath the hood, but for your is illustration purposes. What we've done here is we have a yell property that is ah, we also have a name property that comes with this function, which is the name of the function itself. So the name of the function is who and then it's also a culpable object that is, it can be invoked. Remember these brackets? Well, it's almost as if we can use this notation. And whenever we run the function, it's a cola bill function. We console dialogue. Well, who now if I actually ran this coat, it wouldn't work. I just wanted to show you what is happening underneath the hood to review. It looks something like this. If we had some function well, it would be an object. Think of this orange box as an object with some special properties. One, It has a piece of coat that we can invoke with this these brackets. And when we invoke with these brackets, it reads, whatever. The piece of code is inside of that function and it executes it. Another thing it has. It has a name, property that is optional because, remember, we can have anonymous functions. So if this function was called some funk, the name will be some funk. But if we let's say used function expression assigned it to a variable. But the function itself is anonymous. Well, name wouldn't exist because it's optional. Another thing we get is we get properties automatically on a function, and we've seen them before. We have properties like call, apply and bind that allow us to act upon that function. For example, if I go back to woo hoo, I can do call and we see that we have this method available for us. If I go back, we see that, Yeah. Look at this. This purple box. These are methods that we have, and then We also have properties like arguments. Length, name. Remember the name So that if I run this Look at that. We have Woo hoo. Now what about objects? If I created an object, would I have those properties on there? Well, let's see. Object dot I don't have called, do I? I don't have bind. I don't have arguments. No, I don't have that. Remember what I said? Functions are objects and they're a special type of object that is a cola ble object with the bracket notation for invoking the function contains the code it has name and it also has some properties like call, apply and bike. But why do we care? Why is that really important? You see, because functions are just objects in javascript that means we can pass them around like objects like things that contain data. So besides just doing things for us and performing actions in our code, we can also store them as data, move them around and have some really interesting applications. And that's what we're going to explore over the next couple of videos. Let's dive in 51. 03 First Class Citizens mio: welcome back in the previous video, we talked about how functions can be passed around like data and this idea of a function being passed around. Besides just being something that performs actions. And because of this, you'll after hear people say that functions are a first class citizen in JavaScript. What does that mean? Well, it means three things. Let me comment this out. The first thing is that functions can be assigned to variables and properties of objects so that I could do variable stuff equals to function in some languages. I can't do that. I can just run functions to perform actions, but that's it. In JavaScript, I can assign it to a variable or even object property, which then becomes a method. What else can we do? Well, we can also pass functions as arguments into a function so I can do function A that receives another function. And inside of this function I can run that function and then maybe we can call a with a function inside of it function console dot Log Hi there. So that if I run this code, I get high there, I am able to pass a function as a parameter to a function. I no, I'm saying function a lot. So I'm passing this which I can extract it away to a variable like we did up here at one and pass it around like data. It's almost as if I'm just passing it as a strength. And I'm saying, Hey, here's here's some data for you. Run it when you get into function. A. So that's very interesting. And in the final piece of the puzzle is that we can return functions as values from other functions. What does that mean? Well, I can do this. I can say function be that returns another function, see? And this function c Contains consul dialogue. Fight. So now if I run be, I get function, See? But if I run that again, I get by or I can even assign it to a variable and then just call that valuable D. So those are the three properties that make functions. A first class citizen in JavaScript, we're able to assign two variables the's functions. We can pass these functions into arguments, and we can also return functions as values from another function. And this goes back to what I said. Right functions are data. Not only do they perform actions for us, but they're also pieces of data that could be passed around like first class citizens as if there were JavaScript types. So anything you can do with other types you can do with a function. And as a matter of fact, this idea of a first class citizen property in JavaScript introduces JavaScript to a whole world called functional programming an entire section that we have coming up. So now that we understand why functions are first class citizens, let's dive deeper into some of the interesting things we can do with it. Now I'll see in the next one, but I 52. 04 Extra bits of Function: Welcome back. Let's do a quick little video on some of the things that you want to watch out for with functions. The one thing is, you want to be careful of initializing functions inside of loops. For example, if I had a loop here, let's say for let I equals zero and we'll say that I As long as it's less than five, we will increment I. And in here if I had a function A that gets initialized well every time we loop over here, So when I equals zero, we're going to initialize the function A. And then perhaps we run the function. And then when I becomes one once again, we initialize the function added to memory and then invoke the function so on and so forth until I becomes five. You want to be careful here because instead of initializing the function in a loop five times like we do here, we instead should be moving this up top so that we initialize the function just once and then when we loop over it, we're just executing it five times instead of initializing it and executing it. So that's something that is often overlooked and you want to be careful off. Another thing that you want to be careful with is something like, Let's say we had a function that returns some parameter and if I run this, I get on to find because I haven't called yet. So let's call that if I run this I get a reference air program is not defined. I looked at my variable environment. Hate do I have Paramus? No, don't have it. Keep looking up the scope chain. So I go up to the global variables and I asked, Hey, is prime there Don't have it. And as soon as we have nothing in our variable environment and nothing up our scope chain, we get a reference air. This often causes a lot of functions to fail and involves us always doing some sort of a check to see. Hey, does Paramus exist? Or is it a number, or is it a certain type? Now we could in here at a program, and if I run this, I won't get that air because when we add a parameter to a function, it adds it automatically to our variable environment, as if we just declared that variable. But when we call it with nothing. Well, we're going to get undefined. So one way you can avoid this is if you just give it a default parameter, which is new with ES six. So if I do, Haram equals 26 and I run this. Look at that, I get six. So it's good to have default parameters set on a function as a way to avoid those cases. Now, these are just small things, and there's many best practices when it comes to functions. We're gonna explore those a little bit later on in the course. So for now, I'll see you in the next video, but by 53. 05 HOF mio: Welcome back. Let's talk about higher order functions now. Higher order functions are simply a function that can take a function as an argument or a function that returns another function. That's it. That's all higher order function is. But the big problem is that most people know what higher order functions are but don't really understand why they're useful. Why we care. So my challenge in this video is to make you understand why higher order functions are useful. Let's get started with the 1st 1 Let's start off with function and see what sort of problems we have with just a simple function. Let's say we're creating a system for our company where we have to let users log in. So I'm going to just naively create a function called Let Adam Log in In this simple function is going to do some sort of work to authenticate the user, in my case, just to keep things simple, I'm just going to create an elaborate on empty array, and we're going to simulate the type of work that the system might need to do. So let's do a for loop that says, Let I equals zero. That's not zero that so And let's say I is less than a big number. And then finally we incremento i one by one, and in here we'll just do ray dot push the index. So we're doing something completely useless, but just to slow down our system so that at the end of it, hopefully everything works out and we can just returned access granted to Adam. Good job, Adam. So that if I run, let Adam log in. I get access granted to Adam, But you saw that there was a bit of, ah, pause there. If I add an extra zero here and I run, you see that there's a bit of time that takes to grant access to Adam. So for now, just think of this as a some sort of an authentication log in service that the company has . All right, so that's great. We just created a function that lets Adam log in. But our company has MAWR employees, right? What if we also have a va? Well, Eva needs to log in as well, so let's create another function for Eva now. This function for Eva instead of let Adam Log in, will be let Eva log in and will change access granted to Eva. And then we can call that function. Let Eva log in. Now I'm going to change the zeros here. Just so it's a little bit faster and I could run. There you go. Access granted to Eva. Perfect. Now what's the problem with this coat? The principle that we always hear as developers dry do not repeat yourself. We've created some code that is not very flexible, right for each user that we have. We have to copy and paste coat and repeat ourselves. And imagine if we had hundreds and hundreds of employees doing this every time. Well, that's, Ah, that's not very clean, is it? It's not very efficient. It's not very easy to read or reason about. So how can we fix this? Well, let's move on to our next level. Let's go from a simple function to a function that, except parameters to gain some superpowers. Let's have a look. Instead of doing this manually, let's remove this and let's create a generic, let user log and function, and this user is going to accept a parameter user that will give access to some user in this case, Well, let's extract this piece of code out first. So let me copy this out. And ideally, we want some access to be granted to a user. So let's say I do let user log in and I'll do Adam, if I click run here access granted to Adam and then if I do they user log in to Evan. And by Evan, I mean, Eva, I get a bus, um, access. Now let's re factor this code a little bit to make it cleaner. I'm going to create another function, and dysfunction will just be called Give access to that. Accepts a user and this user. And you know, let's use a narrow function here just to change things up. And this air function is going to return access granted to the user. Or let's just say name so that were being descriptive here. No, due to the nature of arrow functions and because I only have one line, I can do this and not wrap it in a curly bracket, and this automatically gets returned so that now I could just say, give access to So what superpower do we just gain here? Well, we leveled up over here because in here we've done something amazing. We now tell the function what data to use when we call it. So remember, before we had a function and that function when we actually called it, decided what to do with that data. Instead, we now have a more generic function that says, Hey, I'm going to give you later on some generic piece of data. I don't know what yet, but when I pass, you the user do some sort of functionality to it so that instead of defining Eva or Adam inside of the function, we can just define that later on when we actually invoke the function. So we have the ability when we call the function to define the data. So we essentially have a bit more flexibility instead off. When we define the function, telling it exactly one needs to be done. We can delay that until execution time. And this gives us as you can see, more flexibility. We kept our code dry. Awesome. That's great. But, um, I thought we're gonna talk about higher order functions. Well, let's see how we might have another problem here. What if we have instead of just a user. We also have the mint. Somebody with a lot higher privilege. Well, we'd have to copy this coat and this time around, say, let ad men log in. Let me remove the comment from here and this time around, instead of just a simple user. It's an men and this and men. We have to give it access, but because there and men, they have to go through a bit more security procedures. And let's say it takes a little bit more time for them to get authenticated. So the function has changed a little bit. We have a different loop here, a different permission process. So what do we do here? Well, we just copied more coat were not being very dry, are we? And imagine if we had many more roles in the company instead of just users and ad man's. Maybe we have managers. Maybe we have secretaries. Maybe we have guests access. So what can we do here? And this is where higher order functions are gonna come into play. Remember this? We ran from functions with functions with parameters that way, instead of just saying when we define the function exactly what to do and what data to use . We're able to now say, Hey, we define the function what it does, But later on, we'll tell you what data we need with a higher order function. We get to do both of those things. When we actually call the function that is, we can give it the data and also tell the function what to do or some extra abilities when we actually invoke it. So let's see this and coat this time around. Let's create an authenticate function, and this authenticate function will take a parameter, which is the verification process in our case will just give it a number, which is the time off authentication. So let's just do verify. And inside of this function, we can just remove this authentication process that we keep writing everywhere, and the number will just be the parameter verified so that it's more dynamic and we can change according to the user or the admit. So we have the authenticate and just for fun. Let's just return true, saying that Yep, we've verified everything you can have access, like I said, a little bit of ah, useless code right now, but I hope you get the idea. Now we have the authenticate function. We have the give access to function. How can we make these functions better? Well, instead of let and men, Logan let user log in. Let's remove these and instead, let's just create a general function. Let person function that except a person as the first parameter and then a function as the second parameter. And remember our definition of high order functions. It's either a function that returns another function or a function that accepts a function as a parameter, so that if inside of here, I say, let's do a simple check saying person dot Level is admit in that case will call a function with the five or 500,000 loop. Remember, this is gonna be verify later on, and then we'll say else if person dot level is user, their level of authentication won't be as intense. Soldiers say function five for 100,000 and then afterwards we could just return, give access to, and then this person will also have a name. So how did this make things easier? Well, let's have a look. I can now say something like let person and this person will be an object that has level, user. Remember, this level is going to be used to decide if they're in men or user, and the name will be decided for giving access to that person will say, this is Tim. And now the first parameter is the person. And the second parameter is the function. What should we let the person do? Well, we want toe authenticate the person so that let's make this a little bit smaller, actually doesn't really help. All right, so now we let person authenticate. Let's see if that works. If I run all right, access granted to time because I can spell Tim. All right. And if I change this to a men and let's say this is Sally, I run this access granted to Sally. What power do we just gain here? Well, we've now gained the power to not on Lee. Tell it what that had to use. But we also got the power to tell it what to do. So the function as well. So we created a generic function. Let person remember how we had just let Adam log in. How very specific that was. Instead we have a more generic let person that except a person as a first parameter and then a function in this case authenticate as the second parameter. Now this over here wasn't very descriptive. We could have just said authenticate here as a parameter and have it a little bit more descriptive. But by making things general, we can no do something like this. We can add a function that's a function sink and this Singh will take a person and this person, well, we'll be able to sink. So how's your stew returned? La la la My name is and then add person dot name because our let person function is Mawr General now is a higher order function because it accepts a function as a parameter. Yes, that person is a higher order function, I can now say, instead of let person authenticate, I can say it let person sink. And if I run this well, I'm still going to get access granted to Sally because we have this return give access to function here, but maybe again to make it more general, we can remove this and may be added to the authenticate function right here at the very end . And in here, all we really do is just return some generic functions, remember? Ah, high order function returned other functions So that here, instead of just giving a solid number for men and user, we can just give it the person parameter. If I click Run, Look at that la la, la. My name is Sally were able to make let person be a lot more generic and do many more things to it now. We did break a bit of functionality here, and that's the verify now needs something a little bit more. Perhaps we can do some sort of a conditional saying that if person we pass in the person rate, if person dot is an ad men, then we'll do this sort of authentication. But I hope you get that. What we've been able to achieve with higher order functions is this ability to tell the function what to do during in vocation. We're able to have a little bit more flexibility than we have before. We're able to keep our code dry and a lot more flexible. Let me show you one more example just to make sure that we got this if I had a function caused, multiply by and I want this function to be a generic function that I can just create multiple functions from it, calling them multiply by two. Multiply by, Let's say 10 so on and so forth. How would I go about doing that? You know what? Instead of me just showing you how about you try this yourself and in the next video, I'll show you how we can do this. 54. 06 Exercise HOF mio: welcome back. Were you able to solve this? Let's give it a go. If I wanted to create a generic multiplied by function, I'm going to do a function that except number one a number and inside of this function, it's going to return another function that is going to have a number two as a parameter. And that's simply going to return numb one times numb to and with this in place, I can do multiply by to, and I can assign this to another variable. Let's say multiply by two to equal, multiply by two. And now I have this functionality and dysfunction that I can keep reusing where I can multiply by 24 I can multiply by two. Let's say 10 and I had the functionality over and over. With this higher order functions. What is the higher order function here? Well, the multiply by is a higher order function because it returns another function, and I can also extend this right. I can create something new where I can do multiply by, say, five. And if I do multiply by five year, I can now extent multiplied by five. Let's say multiply six by five we get 30. Awesome. Now we can also write this in a cleaner way with arrow functions. And it looks something like this arrow function, followed by another Harrell function. And we can even one line this. So we go like this to just a single line of code like that. And if I run this, it still works. And I like using arrow functions because visually it makes sense, right? All that's saying is give me a parameter than another parameter. So if I just do multiplied by number one, which should be for and then add another bracket multiply by 66 stands for will be 24 that's all these brackets are showing. You don't get confused by all these arrows. It's, ah, higher order function. But each bracket shows you how to call the function so that we can do something like this Now higher order functions. I hope you start to see the power off them because we're gonna be using them a lot throughout the rest of the course. Now we learned how to go from a simple function to function with parameters. And then finally we went super saying to higher order functions, and the main benefit was the idea of making code more general, keeping our code dry and not repeating ourselves and just breaking things down into small functionalities. Now some people might argue that higher order functions doesn't necessarily simplify our coat. It makes it look more complex and complicated, and that's a subject up for debate. But with this new found knowledge, I think we're ready to get into our first pillars closures. I'll see in the next one, but by 55. 07 Closures mio: we are finally here. It's time to learn the first pillar off JavaScript, and that is closures. Now. As I said before, these two pillars, I think, give you superpowers if you understand them deeply as a programmer. Now you think I'm exaggerating here, but hopefully after these few videos, you'll understand why, especially when it comes to closures. We unlock some really interesting abilities in our programs, so let's learn how to harness their power. We have these things called closures in JavaScript because of two things that we get. One is the fact that in JavaScript functions are a first class citizen, and we already talked about that. We know what that is. We can pass functions around like data like any other type in JavaScript. We also have this idea of lex co scope. That is, the JavaScript engine knows, based on where our code is written before we even run the code. What variables each function has access to, and closure is simply that a combination off function in the lexical environment from which it was declared closures allow a function to access variables from an enclosing scope or environment, even after it leaves the scope in which it was declared. It sounds pretty confusing. Rate and closure is one of the most confusing things, but it's an important topic. So instead of me just talking about it, let me demonstrate with coat. Let's say we have a function. A. And then this function will have a variable called Grandpa that has the grandpa strength inside of it or assigned to it. And then this function returns another function. So it's Ah, higher order function and we returned function. Be from here and function B will have a variable inside of it. Remember function scope that has father again. Same thing string Father. And that function has or returns a function function. See, and inside of that function we have a variable called Son that as string son and finally, through all of that we return, Let's say a template string and this template string will return a few things for us. I will return grandpa all return father, then l returned, son, And let's just adds some symbols just to make it look nice. So I've created some functions here and function a and function be are higher order functions because while the return functions function, see is just a normal function, because at the end of the day were just returning a piece of strength. So let's run this coat this. I run a here and I click run while it returns, function be That makes sense. Right? So I can assign this to a variable and call it again. Or I could just invoke the next. So whatever the invocation of a returns, I'm going to call again, which I'm going to call Faction B. If I run this, I get function. See? No surprises there. What if I run function? See if I click Run. Look at that. I get Grandpa Father, son. And if you've been working with JavaScript, this shouldn't surprise you, right? This is the expected behavior. But here's my question. How did son of all people remember what Grandpa Waas? I mean, if we call function a here and let's just say const power, that's a terrible name list to constant one. Well, we just ran dysfunction. This function was invoked. So the only thing we have remaining is this function. Aid got popped off the stack. So what happens when things get popped off the stack? Well, we remove the variable environment, right? So shouldn't let Grandpa be garbage collected and thrown away because, well, we removed it from the stack. Right? Somehow Son has access to Grandpa and also has access to Father, even after after we call the B function. And this is what closure is. Let's visualize what's happening here with a closure. And by the way, this little box is going to be our closure. When we run the A function first, well, it pops onto the stack or it gets pushed onto the stack and we create a variable environment, right? And this contexts execution has grandpa as a variable. It would also have parameters here, such as, well, the arguments, keyword. But because we haven't given it any other parameters, there's no other variables here. Just Grandpa and this Grandpa, once we call function a well, what's going to happen to it? We have the chain here, remember, that gives us a link to the global scope. That means if there were any variables in the global scope or global execution environment , then we might have access to them. But for now, in here, once this gets removed off the stack it's gone, but Grandpa still remains. And that's because Grandpa over here goes up into this box of closure. Now, why is that? Because this box over here is technically where the memory heap is right. It's a bunch of memory, and as soon as we don't need things anymore, what we need to remove it. However, when the garbage collector comes sees, Grandpa says Who? There's a closure here. It's in the special closure box in this closure box. I can't clean up because there's something that is referencing Grandpa from inside of it. So the next be function gets called again. We added to the stack a new variable environment dis created, and we have father there. Once we remove father or once be gets popped off the stack. Well, once again, Father is being referenced by another function inside of it. So gets put into this closure box and then see, comes around, finally gets called, and we have son variable here. Now when we return the statement, Grandfather, Father, son, the sea variable environment is going to return and say, All right, let's find out what the grandpa variable is. It's going to look in the variable environment and say Nope, I can't find it. But then now, instead of looking in the global scope or global variable, it looks in this little closure box and says, Hey, do you have grandpa? Yep, I do. Hey, do you have a father? Yep. I do. How cool is that? And JavaScript does something unique here, Right? The JavaScript engine will make sure that the function has access to all of the variables outside of the function. With this closure, that is this little box. So closure is a feature of JavaScript. Let's go back to our function again. Because function see is inside. Oh, function a and function be the JavaScript engine is going to say All right, I'll create a closure for you. All of the variables outside off the sea function. I'm going to keep around. If C is using it, that is, If we had another variable, let's say let random and then it's a random number. Well, the JavaScript engine, once be is invoked, isn't going to keep random around because, well, it's gonna get garbage collected. Nothing's referencing it, but the JavaScript engine is going to keep any thing that's still being referenced by a child function. In this case, C still needs father and Grandpa, so it's going to keep it around. And closures are also called lexical scoping. Let's think about that. We've seen that before, right? Lexical scoping lexical means where it is written. Scoping is what variable we have access to. So by that definition, that means the JavaScript engine before we run any code before we get to line 12 or line 13 already knows which function has access to which variables. Because JavaScript is lexical e scope or statically scoped. It sees during the first face where it looks through our code and says, Oh, yeah, I'm gonna keep grandpa around. I'm gonna keep father around even if it gets cold, because I'm gonna create these scope chains for us. Remember this. We had this little hidden property scope that created our scope chains and what we have access to so that the JavaScript engine before we run the code has these little links between the functions, and this works because these values are not on the call stack. Instead, they're on the memory heap, right, and the heap just gets cleaned up by the garbage collection. But the job script engine says, No, no, no. We still need some of these variables, so why can we use closures again? That's because off what I just mentioned, we can have functions that return functions, functions as first class citizens. And we have this idea of lexical scope. Where we write the function matters not where we call the function or where we invoke the function. Let's look at another example. Let's say I create a function called Boo and Boo takes a strength, and inside of this function, we're going to return another function that will take name. We'll have another function inside of this that gets returned. This will be name, too, and then inside off year will just console dialogue. Let's say hi. Or actually, let's just Consul log three things that is string, name and name, too, in a cleaner way of writing. This with air functions is to just simply do this. So let's do a const boo equals string, which is an air function which is also going to return a function that finally returns console log so we can just remove all the brackets just like that and keep it on one line and because we only have one line here, we don't need any curly brackets. We have consul lot so that now if I run oops, I do need the bracket. If I run boo with, let's say hi. Well, I get a function that makes sense of irony with Tim. Get another function. If I run it with Becca, I get high. Tim. Becca. And if you haven't realized why I guess so excited about closures and why you should to is that we can have some hidden powers now, for example, imagine if we just did boo. Hi, I know this. This is a terribly named function, but let's say that we have boo string here that equals boo high. And then let's wait. I don't know five years and then do boo string name. And then we're going to call do strength now. Obviously, I just commented out here, but what I'm showing you here is that when I call Boo High and added to this variable, let's at a concert here and a constant I could hypothetically, if the JavaScript engine is running, wait five years and then finally call boo Strength and boost string, even though it will be off the stack or the boo function is off the stack will still remember for me this high that we gave it five years ago. That's because, remember, parameters are treated just like local variables that gets stored and variable environments so I can wait five years and hold on to Information in memory doesn't get deleted, and I can call it whenever I want. Let's take a break and revisit this idea some more. To understand its true power. I'll see in the next one, no way. 56. 08 Exercises Closures mio: Welcome back. Let's do a fun little exercise. If I run this function, call me. Maybe what is going to happen? This should be fairly obvious, right? If I Ron call me, maybe we're using said time out here. And if I run, I wait a few seconds. Four seconds. And then look at that high. I am not here. I get a call back. That's great. And what do we use your for us to do this if you've guessed Closures. Good. You've been paying attention because we have a function in here that if you remember the way set time out works is it gets sent to the web ap I to start a timer for four seconds. And then once that timer is gone, we send this piece of code to the callback. You and the cold back. You is gonna wait there until the call stack is empty. So call me. Maybe has been called. It's now popped off the stack, and the event loop is going to push this function onto the stack and running, and it's going to console log. Call me now. This variable call me has technically well, it should have been gone right? Call me. Maybe has been popped off the stack by the time this line gets run but because of closures . And yes, even if some of the functions go all the way out to the web ap I world well, they still use closures and were able to remember this variable because of closures. So let me ask you this Based on what you know about closures, if I remove that variable from up there and I put it down here, what's going to happen? Can you guess before I had run, Think about this and let's find out. I run the function. I wait. I wait and I got it back. Why is that? Well, because it doesn't matter where we define this variable. Yes, even if it's constant that doesn't get hoisted. We don't care about hoisting here. Instead, this piece of code goes all the way into web ap I world gets put on the coal back to you. The event loop pushes it back onto the stack. But by that time, we already ran dysfunction. Const. Call me has already been created and assigned and because it sees that there's an enclosing function that is using it. It's going to create a closure. How cool is that? All right, let's take a break and do some more exercises. I'll see in the next one. Bye bye. 57. 09 Closures Benefit1 mio: Welcome back. I feel like you're still not really convinced. I bet you're thinking, Andre. I feel like you're over hyping closures. They're not that exciting. You said is going to give me superpowers. Well, maybe this video will convince you otherwise. You see closures have two very important main benefits. I mean, they're obviously a lot of benefits, but there's two that I really want to focus on, and that is they can be very memory efficient. And it also allows to do something called and Cap Soleil Shin. I hope I spell that right now. These two things are probably the coolest part about closures, and I hope that this is gonna blow your mind. Let's start off with the 1st 1 Memory efficient. Let's say that we have a little function. I know all my functions, I say, are fun, but I think this one's extra fun. All right, let's say I have a function here and we'll call it a heavy duty function and this heavy duty function well, it's heavy duty because we're gonna create a big array here in a nice, easy, simple way to create a massive array is to do something like this new ray, and I'll fill it up with seven 1000 entries and use the fill method that comes with the race and fill it in with a smiley face. And in here we'll just return Big Array. So just to test it out, let's see what happens when I run Heavy duty, I click. Run, all right, lots of smiling faces. Everybody's happy. That's great. Okay, but let's say that obviously, this is a silly example. But let's assume that this is a very heavy duty operation that we need to do. And let's say that maybe this operation is about accessing a massive array. For example, if I do item here, I can access Videgaray by the index number. So let's say actually, instead of item, let's do index here. And if I do index, I can access different parts of the array like 600 or 688. And if I run, this index is not defined because I can't spell. Let's try that again. Click run. There you go. I'm accessing the index of New Ray. All right, So far, so good. But let's say this index 6 88 is someplace and maybe a database or just Honore that gets access to a lot. What if we call this function many times many, many times, every time I run it? Well, right now we can't see. So let's just add a consul Dialogue created, which will be a strength that we run four times. And in this case, we see here that we're creating a big array, adding data to our memory, which we have limited memory of were creating it every time. So every time we run this function, we create this memory and then we return it, and because nothing's referencing it, it gets destroyed, and then we create it and then gets destroyed. We created and then gets destroyed, be created, and that gets destroyed. All right, that doesn't sound very efficient. Wouldn't it be great if there was a way for us to create this array and because we know it's going to be used a lot two on Lee created once and just have it in memory there, so we can just constantly access it instead of doing all that work? How can we do that with closures? If you want, pause here and try and solve this yourself. Otherwise I'm gonna get going instead of using the original heavy duty function. Let's create another function down here, and this function will be called heavy duty to and heavy duty to well will be a function that for now we can just copy from up above right here. Let's do that. And I'm going to remove some of these very so heavy duty to we're going to make some adjustments to it. So it to use this closure, The first thing that we should think about is, well, a closure returns a function. So we want toe add this to that little closure box and then return a function that holds a reference to bigger rate. So let's do that. I want to change this to created again, and in here I'm going to create a function that receives the index and inside off year, we're going to return big array of index nothing that much different from above. Except for one thing, right, we've created closure. That is, we have a reference to big rate. Let's see what happens if we run this. I'm going to run the heavy duty original function three times and then I'm also going to create a variable called get heavy duty. And this variable will actually use the heavy duty to function. And the heavy duty to function actually doesn't even need the parameter index anymore. Because index is something we're gonna pass to the function that gets returned from it. So here, I'm just going to call this and then I'm going to just say, get heavy duty and call 6 88 maybe call something else as well. Let's do 700 and then get heavy duty. Finally, 800. Let's just remove the semi colons. You don't really need those. Now if I run this Did you see that now? Obviously, I'm able to use get heavy duty or heavy duty to up over here because well, off hoisting right function declarations get hoisted to the top. But we see a difference here, right? The first heavy duty was well created three times versus heavy duty to where we use closures. We were able to create the bigger a once and because we knew we were gonna access it a lot . We just maintain that closure scope over it and were able to call it over and over without doing all that creation. Destruction work. How cool is that? All right. Still not convinced that closures air cool? Well, how about the second benefit of closures? Encapsulation for that, I'll see in the next video. 58. 10 Closures Benefit2 mio: Okay, so you're still not that impressed with closures. You're a tough cookie to crack, but maybe with encapsulation, I can convince you otherwise. Let's create a serious function this time. None of those funny, silly functions that I keep creating. Let's have a const make nuclear button function and this function well, do a few things. Actually, the first thing that is should do is to launch a nuclear bomb. So let's do that. I'm going to create a launch function, and this launch function is going to return a big boom. All right, so that's our launch function. And you know what? I want this function to maybe do more than just launched stuff. Let's Ah, let's have a countdown. Or let's figure out how much time we have without the box. I'm sure you wanted me. Let's create a variable called Let Time Without destruction and Time Without restriction, destruction will be zero, and we're going to create a little timer that counts how long it's been since, Well, we've had this mutually assured destruction. So in here I'm going to have a variable called pass time and this past time variable or function in this case, which happens to be signed to a variable. We'll simply have time without destruction and increment that time. And then finally, to make all of this work, I'm going to add a set interval which is like set time out. But it keeps running the function that we give it. So in this case I'm just going to run pass time. So that is to increment the time without destruction by one. And we'll do that every one second. Alright, so I've created this. Nothing's being returned from this function. Let's return a few things. I'm going to return on object that has the launch function. And let's maybe also make a total peace time function that simply gets the time without destruction. So let's create that first, let's say total peace time at a common here and then I'm going to create another function called const. Total peace time, which will just return for us the time without destruction. Nothing too crazy here. And you know what? Just to keep in line with everything. Let's with the launch before we return the bomb. Well, change time without destruction to equal minus 10 no, that's not good. Okay, so Let's see if this works. Now I can assign this to a very Bullis A cost. Oh, no. And oh, no is going to say make nuclear bomb or nuclear button and we're going to run this by click run while nothing happens because we have to actually run something we've just assigned a object to. Oh, no. So by come down here and say, Oh, no dot total peacetime and I run this function well, I get zero. This is actually a little funny, but because off the environment that I'm using this actually, the set interval won't work properly. So let's use the developer tools Instead. I'm going to copy this function, Open up developer tools and copy and paste this. Let's see what happens. I got a refresh this. Let's try that again. I get zero If I do Oh, no dot Total peace time again. I get 12th 12 seconds have passed. What if I wait again and run this? I get 18 seconds have passed. All right. We have a lot of time with peace. That's great. And then I run this again 24 seconds. But then all of a sudden and I decide I'm going to launch. Oh boy, do we have a big explosion? And if I go to total peace time while we're back to for again, that's no good. But are functions working? Let's go back here and let's refresh so we can see the window again. All right, I hope this function isn't too confusing, but let me demonstrate something to you we used here Closures, right? The time without destruction is something that thes functions have access to. But we also don't really want people to have powers like Launch, right. So instead, let's remove the launch function from the returned object and instead just have total peace time so that if I Ron launch now, no launch is not a function, and this is what encapsulation does. It's hiding of information that is unnecessary to be seen by the outside world or manipulated. And this gets into the idea of principle of least privilege, a big security principle when it comes to programming where you don't want to give just anybody access to your a p I to your special functions or variables and using closures, we are able to access things like time without destruction that I don't want anybody else touching because I just want to set interval to constantly increment that. But at the same time, I still want people to have access to things like pass time so that that pastime function can access the variables that are sacred to me. And this is one of the main benefits of closures of data encapsulation. And it refers to the idea that some data should just not be directly exposed and were able to do that now, later on. In the course, when we talk about modules and JavaScript, you'll see that classical module patterns like people used to use with immediately invoked function expressions, use this pattern, and we're on Lee able to do that because of closures. All right, I hope you now truly understand the power of closures. I think it's time for us to do a couple of exercises, though, so I'll see you in the next one. Okay, 59. 11 Exercise 2Closures mio: Welcome back. Let's do an exercise. Let's say I have a function called initialize In this function. Initialize is, let's say, a view of some sort. Perhaps it's a webpage, and this is the first functions that initialize is the view off your webpage. Now you want to create this function, but you're also hoping that people don't abuse it because we have it out in the open in the global scope. So people may be somebody that's new on your developer team comes in and by mistake, doesn't know that this thing should be on. Lee called once and instead in their code, they initialize a bunch of times. And maybe this is not what you wanted to do, so that when I run this, you see that we set the view three times, perhaps even resetting the webpage and what the user was doing currently on the webpage. That's not good. That's a bug, right? So using what you know about closures, can you turn this function into a function that can Onley be called once so that even though somebody might abuse it and run it a bunch of times as long as the function has been run once. Well, it's on Lee going to run that one time. Give it a go, and in the next video we'll see what we can do. I'll see in the next one. 60. 12 Exercise 3Closures mio: Welcome back. Let's see how we can solve this issue. Now, I'm gonna do a naive approach to this, but there are many ways of doing it using closures. So let me show you my way. If I wanted this to only be called once. Well, ideally, I have a variable in here called called and maybe it's a counter off. How many times the function has been called in here. I want to keep track of this cold. I want to use closures and keep track of it. But I don't want people outside of this world touching it. So I'm going to return a function. So I haven't enclosing function that surrounded by another function. And in here I can reference cold, and I know that I'll have access to it, even though the outside world won't have access to it as soon as the initialize gets popped up the stack. So I'm going to just simply say, if cold is greater than zero. Well, in that case, just return and do nothing. Otherwise I'm going Teoh. Well, set the view and then finally, we also want toe increment called to say that Hey, we've updated. Called this function has been called. All right, let's see if that works. If in here I do Const. Start once and I do initialized now I can run, Start once once and let's see what happens. All right, view has been set. We see the mountain. That's good. But if I Ron star once again look at that view has already been set. So now it doesn't matter how many times I call it. It's not going to work now. You might be asking yourself, Well, Andre, that new programmer can still call initialize, but I'm going to leave that for you to figure out how to do. In that case, we can, perhaps to use encapsulation and Onley return the star once after we've initialized something. But I'll leave that to you. If you've got in this good job, I think you're start to get closures. Let's do one more exercise 61. 13 Exercise 4Closures mio : Welcome back. Here's another exercise for you and here's a hint. There's actually two ways of solving this problem. So let's see if we can find both solutions. And I'm using this question because it has to be one of the most commonly asked interview questions for JavaScript developers. So hopefully you're able to understand it. I have an array here and also a loop over this array, so we're just looping over the array and we're running said Time out. So we're calling that Web a P I and we have a callback function right here that will be called and three seconds that will console log. I am at index off high. So if I click run here, what's going to happen? Well, let's find out when I click. Run, I'm waiting for set time out and it's back. I am at index for 444 Is that what you expected? If there wasn't? Look at the function carefully and see if you can fix this so that I logs 12 34 and I'll see you in the solution video. But my 62. 14 Exercise 5Closures mio: All right, let's solve this brain buster. Now, the easiest way to actually solve this is to change the bar keyword to let because if I run this and we wait, Look at that. I have 0123 And I guess we're not logging. The actual valleys here were logging the indexes. So if we want to log the actual values, we can just go like this. Click, run. We wait three seconds and we should have everything said. And hopefully you know why that works. Let allows us to use block scoping so that this block, which is thes curly brackets over here, creates a scope for each I so that I is scoped within here. Because initially when we had a variable, I over here, it was part of the global scope, right, because we didn't really have a function surrounding it so that this set time out when it finally returned. By that point, the four loop has already gone through everything. Hand has turned I and do for all right. But what's another way that we can solve this? What if we couldn't use the let keyword? We can use closures here to actually do something interesting. We can actually wrap this in a function so I can create a function and immediately invoked function that wraps this entire set time up. And this function is going to wrap our little said time out. So now in here, we can reference I and as long as we reference I, it won't be removed from the local scope or at least the reference to what I is when the loop comes through here and I can do that by passing this immediately invoked function a parameter off I that is. We call this function and this function gets parameter I which every time it loops over, it'll be 012 before and we received that parameter right in here and just to keep the name separate will say closure I And now we can access Close your eye like this. Let's see if that works. If I run this, I wait three seconds and look at that. It's working. I know that's a tough one. You might have to look at this a little bit, but all I did was I created a function that gave me access to the I variable and this eye variable. I kept in my closure by passing it as a parameter, receiving it and using it inside off this callback function for it. I think that was a big one. So let's take a break and I'll see you in the next video. But by 63. 15 Closures Conclusion mio: And there we go. We learned the first important pillar of JavaScript closures. We learned that a closure is the combination of a function and the lexical environment from which it was declared. And we're able to do this because, well, functions are a first class citizen and we have lexical scope in JavaScript. And now the statement that I made at the beginning of this closure section should make sense. Closures allow a function to access variables from an enclosing scope or outer scope environment, even after it leaves the scope in which it was declared. Because all that matters in JavaScript is where the function was written. Now the interesting thing about closures is that JavaScript really popularized this idea that is now all over programming languages, especially functional programming languages. And the closure concept is now adopted and added two different languages, like python and Ruby after JavaScript popularized it and showed how powerful it is. And I think C Sharp and C plus plus even are also adding closures to their language. So it's a very, very powerful tool. I hope you had fun with that section, and we have one more pillar to go. So for the next one, I'll see in the next video nobody 64. 16 Prototypal Inheritance mio: Welcome back now. I told you, they're two pillars in Javascript that I really, really important. And powerful. One was closures and we covered that. But now it's time to learn about prototypes and specifically, prototype away inheritance. Let's see if you find this as fascinating as closures. Now I have to give you a bit of a warning. This part is going to be really tough. It may seem convoluted. A times You may have to revisit the videos a few times, but keep in mind what we're gonna learn here will help us understand object oriented programming coming up in the next section. So hang in there because some of this is going to overflow into the next section where you're gonna learn more and more. All right. You ready? I hope I didn't scare you off. Let's get started. Remember this diagram? I told you that a raise and functions are just objects in JavaScript. Let's dive a little deeper into this. You see, Javascript uses something called prototype all inheritance. You see these chains over here? Their prototype Elin heritage. And what does that mean? Well, inheritance is an object getting access to the properties and methods off another object. So what I'm saying here is that the array object again. Remember, everything's an object. The array object gets access to the properties and methods of the object and JavaScript and same with functions through this chain that we call prototype all inheritance functions, get access to the methods and properties off objects. Now let's demonstrate this in code. There's a special way that we can actually see this chain, this prototype, all inheritance and jobs. If I create an array here, let's say array just an empty array and I do a ray dot Underscore, underscore proto for prototype full inheritance and then underscore underscore and I hit. Enter, I get this thing, it looks like an array. And if I open it up Yeah, it looks like Honore, right? I have all this reduce push, pop Matt methods that arrays get what happened here? Well, I created a new array in this new array was created from yes, this big array box over here what we call a constructor. This array created our array variable that contained well on empty array. And I did dot underscore, underscore proto underscore underscore to go up the prototype chain and get into this array . So by that theory, if I go up the prototype chain, I should get on object, right? Let's have a look if I go back and do array that pro and then go up the prototype type chain again, I get the object or Robbie called the base object. This is the object that everything in JavaScript gets created from including functions and including a race, and we see that we have some properties on here. For example, we have the two string method over here, which means that anything that is a descendant of an object will get the to string method. So that means that an array such as our or Ray over here has the to string method on it. Look at that because of this prototype chain. Remember what I said? Initially, an object gets access to the properties and methods off another object through the prototype chain. Let's further this example this time around. Let's create a function function A and this function a well. There's just empty once again, if I go up the prototype chain, what do you think we'll get? I get this F over here a native function. And this is our base function where all functions are created from so that if I go up the prototype chain again, what do you think we'll get? Yes, we go back to that object, that base object that all objects come from. All right. One last example. Let's say I create an object object one, and this is going to be an empty object. Let's refresh to make sure that we haven't declared it before. Now, if I do object one dot proto, what do you think will happen? Well, we get the base object again. This base object is this one over here, right? I created from this object, my own object variable, and that inherits has a prototype chain up to the space object, and this is what prototype all inheritance is. It's a concept that over the next couple of videos, we're going to understand why it's so useful to us. As a matter of fact, this feature is actually quite unique and not that common. And other popular languages like C sharp or Java, they use something called classical inheritance. JavaScript uses prototype all inheritance. Now, even though in javascript we do have the class keyword, and it's something that we're gonna talk about in the object oriented programming section of the course in JavaScript. This is what we call Singh Tactic, Sugar. There's actually no classes in JavaScript. We only have prototype all inheritance. So what is this whole prototype chain wise and useful? Well, we just started here, so let's dive a little bit deeper in the next video. 65. 17 Prototypal Inheritance 2 mio: Welcome back. Let's do a fun little demonstration off the prototype chain. I'm going to create a dragon, and this dragon will have name as the property that let's call that dragon Tanya fire. Well, it's a fire breathing dragon. So obviously that's set to troop and the dragon can also fight. So this fighting dragon will return. Let's say damage off five. That's a pretty strong dragon. And you know what? Just to make it more fun, we're going to add a sink method to this object and we'll say it returns. Astute templates. Drinks. I am this This start Name the breather off fire. I am Tanya. The breather off fire. That should make sense. Now if we do dragon dot sing have a syntax error because I forgot a comma. Let's try that again. I am Tanya. The breather off fire. Nice. And if I do fight here, I also get five. Perfect. Now let's say we have another object now, and this object is just a simple lizard. And this lizard, unfortunately, doesn't have much power. It has a name off Kiki, and then maybe it can also fight, but definitely not a strong us. The dragon. So it's only going to give a damage off one, huh? Not a very strong lizard. Now, if we let's say, wanted to borrow a method from the dragon object. We've learned how to do that before, right? Remember, bind. Well, I can just do something like Const Sing lizard and this constant lizard sing lizard will have the dragon dot sink dot find and borrow that method for the lizard object. So let's Consul don log, sing lizard and run this function. Let's see what happens. I run and I get I am Kiki the breather off fire. Nice, very, very cool. But let's say this object gets a little bit more complicated. Let's say that the dragon this time around Well, in order for us to breathe fire, we have to make sure that we have the fryer property set to truth so that we can perhaps do if this Stott fire, which will be true in our case. If that is true, that's when we return our battle cry so that if I run this now, I get undefined. Unfortunately, the lizard doesn't have fire set to true. And even though we borrow the method because we don't have the fire ability. It's never going to sing. I am Kiki the breather or fire. So what can he do here? I mean, we could manually just add the property. But you can see how you might get more more complicated here, right? What if we had a big object and we want to borrow more than just one method? Want to perhaps inherit a bunch of these properties for the lizard as well to make it all powerful. And this is where prototype all inheritance comes in. What if we create a prototype Jane that says, Hey, I want lizard to inherit all these properties and methods from Dragon. How can we do this? Well, we can go like this. We can say lizard dot Underscore underscore proto underscore. Underscore. That is we're creating that chain from lizard all the way up. Two dragon. All right, let's see if that works. If I do lizard dot sing No, and I run. Check that out. I am Kiki the breather or fire. What about the property fire? That means we have Firas Well, right, Let's do fire or Sorry, just the property fire set to True how awesome. Is that What about fight? If I do fight and I run this well, my power is still one because I have a fight already defined in my lizard object. So what we were able to do here is we were able to inherit through this prototype chain all the properties and methods of the dragon and overrate anything that we've already declared in our own object. So that is name and fight. Stay with us. But as soon as we say something like sing well, the JavaScript engine is going to say All right, lizard dot Sink. Hey, lizard, let's sink. And then it's going to look through the properties and say, I don't see sink here. I'm going to go up the prototype chain because we've created that prototype Shane up to Dragon and see Hey, dragon, do you have a sink? And if Dragon has sing, then it's going to run it using this coat. You know what happens if we call something other than sink? Maybe dance. And if I run, I get no lizard dot Dance is not a function because we go up the prototype chain. Does Dragon have dance? Nope. And then What do we do next? We go up the prototype chain of dragon. What's the prototype chain of dragon? What? We talked about this right? The prototype chain off Dragon is Let me comment out the dance. Here is the original base object so that hypothetically I can use whatever methods this base object has, if you'll remember are based object. So if I go cost object or a constant dragon equals for now on empty object and I do dragon dot Underscore underscore proto underscore underscore I get this base object and I have a few properties here. So if I do, let's say is prototype of which looks like comes with the base object I should be able to use this rate if I do. Dragon Dr is Prudhoe type above and in here I say, Hey, another object whose prototype chain is to be checked So is dragon a prototype off? Let's say lizard if I run this Yep. Dragon is a prototype of lizard. What happens underneath the hood? We tell the JavaScript engine. Hey Dragon, run this method. It's going to look in the dragon object Say Hmm I don't see any method called is prototype off here. I'm going to go up the prototype chain to the base object that all objects are created in JavaScript from including functions in the race. And it's going to say, Hey, do you have this prototype off the JavaScript engine is going to say Yep, I have is prototype of Let's give you that functionality. And for us, this functionality is prototype off does exactly what it asks us to. It asked. Hey, is Dragon a prototype off lizard, that is, Does lizard inherit from Dragon? Yep, it does. So we get true. If I change this around to Lizard Dragon and I run this, I get false because Lizard isn't the prototype of Dragon. It's the other way around. Now you may have noticed something interesting here. Let's take a break and I'll see you in the next video. We'll discuss this further, but why 66. 18 Prototypal Inheritance 3 mio: Welcome back. Let's see if we can do something interesting here. I'm going to remove this line. Remember, we just have dragon and lizard. We're going to once again inherit or create a prototype gene up to dragon. And now here. Let's check something. I'm going to do a four in loop, so I'm going to say it. Let property in lizard that is loop through the properties and lizard. And let's just simply se console dot log, crop or property. I run this. I see that the lizard has properties, name, fight, fire and sink because we've created a prototype chain. Now the base object also gives us another interesting method that we can use called has own property if I do, if lizard dot has own property and we give it a property name, so let's just give it prop, which we're gonna loop over and say If lizard has own property, then we're going to console lock. What does that mean? Well, we're saying with this method Onley log whatever lizard has as its own property. Let's see what happens when I run this. I only get name and fight because lizard only has name and fight the other properties are inherited from up the prototype chain. How cool is that? So we're not actually copying these properties from the dragon? As I said before, if the JavaScript engine doesn't find the property on that object, it goes up the prototype chain, for example. The has own property is not part of lizard. So it goes up the prototype chain to dragon and then up to the base object and finds has on property and were able to use. And the beauty is that JavaScript looks for you through the prototype change automatically . We don't have to do any weird dot Underscoring score proto dot underscore proto proto to find has own property. It does it automatically. And I want to remind you this isn't the same thing as the scope ching that we talked about . Remember, these are the prototype chains, and these are the scope chains, different color chains, right? So keep that in mind, they work in a similar fashion, but they're two different things. No. Before I tell you why this is so useful. If you haven't already figured it out, I do want to warn you what I've just shown you. Well, you shouldn't really attempt. You might be asking yourself. Hey, how come I haven't really seen this underscore Underscore proto before? It seems pretty useful. Why don't we see it everywhere? Well, this underscore underscore proto, although we can use it here, you shouldn't really use it. Actually, you should never use it. It's bad for performance, and there's different ways that we want to inherit when it comes to prototype all inheritance, something that we're really going to dive deep into when we talk about object oriented programming. So we never wanna manually a sign the prototype chain and create that chain ourselves. It's going too well. Mess up our jobs co compiler pretty badly. But I wanted to show you just how it works, and we start talking about object during to programming will learn proper ways of doing this. Now let's talk about why this prototype will inheritance is useful. Let's think about this. Maybe pause the video. Think about it. Why is this useful? The fact that objects can share prototypes means that you can have objects with properties that are pointing to the same place in memory, thus being more efficient. Imagine if we had a ton of lizards, right? And we just copied all this functionality of the dragon onto the lizard into a different place in memory that can get overwhelming fairly soon. Instead, with prototype all inheritance instead of just copying all this functionality into different places in memory, we have it in just one place. Anything that inherits from Dragon will just use this one instance of this method because the JavaScript engine is just going to look up the prototype chain, which makes things really interesting, right? For example, this has owned property that lives on the base object on Li lives in memory in one location because, well, we'll just use the prototype chain to look for it, and everything that inherits from the base object will get access to this. How cool is that? We're being efficient with our coat. We're not repeating ourselves, and we're saving ourselves memory. And by the way, whenever we get undefined on something, let's say in here I go lizard dot I thought I thought and I run this I get a type air or if I go as a property, I get undefined. Whenever the JavaScript engine doesn't find anything up the prototype chain. We get these airs or undefined because it goes all the way up to the base object. And then what happens after we get to the base object? Let's find out if I clear this. Let me refresh and say I have a new object that will create. It's gonna be an empty object. And if we do object dot pro well, I get the base object where all objects are created from. But let me ask you this. What if I do dot Underscore? Underscore. Kowtow again, even higher up than this base object. What do you think will happen? We get no that surprise you. No means there's nothing there. And when JavaScript was created as a language, undefined was used for well, we don't have that variable. We don't have something to find. No meant. There's absolutely nothing there because of its prototype all inheritance nature. We needed some way to say hey past the base object. There's nothing there. There's no some would call this a null pointer, pointing to know it's the end of the chain. Sorry, I got nothing for you. They're throwing error. Throw on to find, say something's wrong We don't have that. All right, let's take a break and getting to more prototype all inheritance in the next video. But by 67. 19 Prototypal Inheritance 4 mio: Welcome back. Let's try a few more things to test out our assumptions. Let's say I create once again another object, and this object has a name of Sally. Now, if I do object, Dodd has own property and I do Sally or name in here. I get true because we have it as our own property. That makes sense. But if I do something like has own property, well, I get false because object itself doesn't have this as its home property. It has this as a property up the prototype change. What about eight function? And this gets interesting because, let's say, have a function called a and it's an empty function. If I do, a Dot has owned property and I say, Well, remember what I said. All functions have call, apply and bind, right? If I do, let's say call. Uh huh. I get false. What if I do bind? No false for that? What about let's say apply? No, not for that. What about name? Remember how he said name is an optional field for a function? Well, yep. Remember, functions are objects and a has a name, right? Hey, dot name is well name The name of the function is a itself, but our call and apply are not as part of the property. You see this diagram that I showed you initially, where a function is a special type of object. It's a cola ble object where we have code that can be invoked. We have an optional name field, as we just saw, and we also have properties that we can add to the function because, well, it's an object. And then I told you that we have call, apply and bind as properties. Technically, this wasn't 100% correct because these properties aren't exactly on the multiply by five function. Instead, what do you think it is? Well, it's up here. It's up. The prototype change. And don't worry. I'll explain this diagram a little bit better, but let's try this with a or let's change this now to multiply by five. So I'm going to create a function, multiply by five. Now it takes a number and this number will both return num times five. So multiply by five. If I go up the prototype chain, we'll have our function, our base function, that all functions get created from remember we've created a function from this base function over here and now this base function. I can capture it by right clicking and saying store as global variable as temp one if I do temp one dot properties. I see all these properties that comes with this function. I have apply bind, call. I have length. I have name because remember, the name is Well, it's an empty name. It's the base function with no name. But I have all these properties and methods on it and up the prototype chain, you can see object over here I also have has on property as prototype of property is innumerable, just like we have it up there in our diagram. So that's actually what's happening here. When we do multiplied by five, we have our proto property that links up to the function and this function over here has the call apply and bind. Now you may notice here there's something called prototype here that the underscore underscore proto links to and once again underscore underscore proto links to prototype and then this proto links to know this is the base object and eventually we link to know we point to know. You see a pattern here, right? We see a pattern like this where proto links to prototype. I know very, very confusing. So let's break this down. Multiplied by five, which is a cola ble object that has code that is in vocal, it has name that's optional. It can have some properties. It also has this proto as well as a prototype property and that proto links up to this function, which once again is a cola ble object, a special type of object that has its own code. It has properties, but it also has this property called prototype, that the proto links to and that's where call apply am, bind, live. And, as a matter of fact, this yellow arrow here underscore underscore Proto actually lives inside of this object. I just didn't included here because, well, I ran out of space. So does your brain hurt yet? Let's test out our assumption. Let's go back to this diagram and test what I just told you. Multiplied by five dot underscore underscore. Proto should point to that base function. Let's clear this first, so let's try that again. We'll do multiplied by five dot underscore underscore Proto, which is a pointer. It points to the function dot prototype. So I get this native function so the native function is function dot kowtow type. This is the same because multiplied by five underscore underscore proto points to the prototype function dot prototype Still confused? Let's try this. What if I do object dot Prototype? Well, I get this base object that we kept seeing everywhere. It's the prototype property off the object. If we go back to the diagram, we see Object that has prototype with has own property and other functions. And that prototype also includes proto as one of its properties that points to know. Let's test that object DOT prototype that has a property underscore Underscore proto that points to know again. I don't think Job scripted agreed Job and naming these things because it is confusing. But remember this diagram proto is simply a reference or a pointer to up the chain prototype object. Let's test this out with well within the range. If I create an array, let's say array. That is an empty array, and this array dot has own property. Well does this array have its own property map Nope, It doesn't remember we're being efficient with our memory. Map functions should live on Lee in one location in memory, up the prototype chain with the base array. So instead, over here, let's do array will be the same thing in here. If I do underscore underscore Proto, which is the property, does that have own property map? And if we do a ray dot prototype, well, we get the base array. And if I do array dot underscore underscore proto, we get the base array so array dot proto is pointing to the father array dot prototype to review or raise and functions are objects in JavaScript multiplied by five is a special type of object that is a culpable object that instead of having call and apply and bind directly as its properties uses prototype will inheritance to actually inherit from the base function. And the key here is that proto points to the prototype up the chain. And keep in mind that this proto property actually lives on the prototype. I know I know very, extremely confusing, but this way were able to be efficient with our memory, were able to use the map function or the four each functions on an array. Just write them once instead of just copying those same methods and properties all over the place. All right, let's take a break and explore some more in the next video we'll see in the next one. 68. 20 Prototypal Inheritance 5 mio: Welcome back. Let's explore how we can create our own prototypes because I told you that proto is something that we shouldn't use. We should never do. Proto equals some type of an object because we should never use this for performance reasons in our JavaScript code. So what is a safe way to do this? Well, let's create a human, and this human will have a property that is, well, mortal. A human is mortal, should be true. And let's say out of that human recreate, let's say Socrates and Socrates should also be a human. It should inherit from this human and we can do that with object dot Create. Now there are many ways of doing this, something that will explore in the upcoming section. But this is one of the ways that we can inherit from human so that I created object that create human. And that's going to equal Socrates so that if I do console dialogue, Socrates and I run well. I get a nem empty object. Let's add a property on Socrates. Let's say Socrates has I must say, age off 45. I don't know how old Socrates was, but let's just say 45. And if I run this I have aged 45. But can I do Socrates dot mortal if I click Run. Yep, I have it. Socrates is mortal because we've created using object or create a prototype chain up to human. So if I do human dot is proto type Both Socrates we all get true Human is prototype of Socrates We've inherited from human not bad at all. This is something we're going to explore a little bit more like I said before. But for now, at least now you know how to do this without using that evil underscore Underscore proto. As a matter of fact, they named it this way so that nobody accidentally messes with the prototype chain. I'll see in the next one. No. 69. 21 Prototypal Inheritance 6 mio: Welcome back. I have one last piece of information that's going to blow your mind. And after this you can relax saying that. All right, no more surprises. The hardest part is over. It's gonna become easier and easier as we learn how to use prototype all inheritance. Now this statement is true. Onley functions have their prototype property. What does that mean? Remember this How proto points to the prototype object? Well, the thing that contains this prototype object is always a function. If we go back to our multiplied by five example, we ask ourself is multiplied by five a function. Well, yes it is. Then it's a special type of object. It has a Nevo Kable piece of code. It has a non optional name property. It can have its own properties, and we can use proto to link up to the prototype but multiplied by five itself. Because I just said in the statement, every function has a prototype property. It has a prototype. Let's have a look. If I clear this and do multiply, let's run that function again. Function multiplied by five and I'll do multiplied by five dot prototype And look at that I have a prototype. Now this prototype itself is pretty empty. When we create a function like this, this prototype we don't really use it just gets created. But we never really make use of it because prototypes Although they are a property on all functions, the only time we really use prototypes is using what we call constructor functions. Constructor functions. They usually start with a capital letter and they contain the actual blueprint or a prototype that we use. So for example, if I do multiplied by five dot underscore underscore proto which links to that prototype we already know that function dot prototype is going to equal exactly that. If I do multiplied by five dot proto proto and then up the change again, which will be the object constructor. Well, if I do object dot prototype, I get the same thing. But now you're asking yourself Whoa, You just told me that prototype properties Onley exist on functions and this is where it gets a little bit tricky because this object is something we've talked about before. It's the base object, because if I do multiplied by five prototype prototype and then one more time proto we'll get? No, because we're past this space object. But if I do type off object here I get function. What? I know, I know super confusing type of object is a function because, well, it has the prototype property. Remember when I talked about standard built in objects in JavaScript? And we have all these things like fundamental objects like object function bullion. We have number and dates like number, math, date string, all with capital letters. Well, if I click on object here, we see that this object is the object constructor that creates the object Rapper. Remember, in order for us to perform an action in a program, we have to have a function rate. That's what a program does. It stores data, and we use functions to manipulate that data. So when we do something like const object equals object underneath the hood, JavaScript has to create that object. And in order to create that object, well, it uses this object constructor just to prove to you that that's the case. If I do type off on empty object now, look at that. I get object because this is now an actual object that we've created from the object. Constructor. No, I am going to warn you, and I know I've been bugging you about this. This can get pretty hairy and complicated, and it's hard to map your head around. But if there's one thing that you take away from this video is that every function has a prototype property, and it references to an object used to attach properties that will be inherited by objects further down the prototype chain. Th