What do you want to learn? Leverged jhuang@tampa.cgsinc.com Skip to main content Pluralsight uses cookies.Learn more about your privacy JavaScript Fundamentals by Mark Zamoyta Learn everything you need to know to produce production quality web applications and web page features with this foundational course on JavaScript. Start CourseBookmarkAdd to Channel Table of contents Description Transcript Exercise files Discussion Learning Check Recommended Course Overview Course Overview Hi everyone. My name is Mark Zamoyta and welcome to my course, JavaScript Fundamentals. I am a software developer and educator in the Tampa Bay area. JavaScript is the language of the web and you'll need a fundamental understanding of this language to create great applications and web pages on the internet. This course was developed to teach you the key JavaScript syntax and features you'll need to learn as a successful web developer. Some of the major topics that we will cover include: the latest JavaScript syntax improvements, organizing your code into classes and modules, communicating with web services, error handling and security, and much more. By the end of this course you'll know how to set up a JavaScript development environment and create great JavaScript applications for the web. Before beginning this course you should have some familiarity with JavaScript. My Pluralsight course, JavaScript: Getting Started is a good starting point of you've never used JavaScript before. I hope you'll join me on this journey to learn JavaScript programming with the JavaScript Fundamentals course at Pluralsight. Introduction and Setup Course Objectives and Overview Welcome to this course, JavaScript Fundamentals. My name is Mark Zamoyta. Let's start off by looking at our course objectives and getting an overview of what I'm going to cover in this course. First of all, JavaScript is the language of web browsers. If you want to run an application in a browser or even if you want to add some simple programming functionality to a web page, the only language supported by these major browsers is JavaScript. There are other languages such as CoffeeScript and TypeScript and others, but those only work because they get compiled down into JavaScript. So this is the required language for web programming. In addition to web browsers we can create applications for desktops. These are native applications and we can build them with the technology called Electron. If you're interested in building native apps on smartphones and tablets you can also use JavaScript. There's a technology by Apache called Cordova and that's just one of several technologies that could be used for this purpose and JavaScript can be run on the server. We see that all the time with NodeJS. So JavaScript isn't just for the web. It's for native applications on the desktop, smartphones and tablets, and it can also be run on the server side. So as far as learning how to program in JavaScript goes, let's see what this course offers. You're watching the introduction now and also in this course module we'll set up our development environment. Then we'll take a look at JavaScript language features and syntax. We'll take a look at JavaScript's many operators and next we'll cover functions and scope. Modern JavaScript now has block scope and that's an important addition to know about. We'll look at objects and arrays and we'll look at the new way of creating objects using classes and the class keyword. We'll also look at organizing our code into modules. We'll cover programming the BOM and DOM. BOM is browser object model and DOM is document object model. We'll look at working with promises and error handling. Then we'll get into data access with HTTP. We'll take a look at forms, how to validate them and work with them in JavaScript, and we'll take a look at several security aspects of JavaScript applications. And finally we'll see how we can build an application for production. So by the end of this course you'll have a very thorough understanding of JavaScript and all its key features and syntax. In the next clip we'll take a brief look at the history of JavaScript. JavaScript Versions and History Let's take a look at different JavaScript versions and the history of how they came to be. JavaScript was created in 1995 by Brendan Eich. This was done mainly to add functionality to the Netscape Navigator project, One of the first browsers. Then by 1997 it was obvious that JavaScript needed to be standardized. It was handed over to the ECMA association in order to become a standard and the first standard was released in 1997. ECMA stands for European Computer Manufacturers Association, and they have a committee that works on the JavaScript standard. The only problem is at the time JavaScript as a trademark term had some legal issues so they decided to call the standard ECMAScript. So today the words ECMAScript and JavaScript mean pretty much the same thing. Then by 1999 the third release of ECMAScript came out. So things were rapidly progressing, but then at this point the browser wars were in full swing. The main browser developers had issues with where the language should go and ECMAScript 4 spent a long time in development. So 10 years later ECMAScript 4 was never released and there was a jump directly to ECMAScript 5. Its nickname was ES5 and that added a lot of functionality to JavaScript that was desperately needed over the prior 10 years. In 2015 we had the next major release of JavaScript. It's officially called ECMAScript 2015 and its nickname is ES6 and the good thing about this release is that the committee, the TC39 committee for ECMAScript decided to put the year and the version number and this way they could have yearly planned releases. So after 2015 there have pretty much been yearly updates to JavaScript, but the vast majority of modern updates came in this ECMAScript 2015 version, ES6. And you'll hear me mention throughout this course ECMAScript 2015 or ES6 and I'm referring to this 2015 release. In the next clip let's take a look at the tooling we'll be using for this course. Tooling for This Course Let's take a look at the tooling we'll be using in this course. We're not going to be doing any node programming directly, but you need to have NodeJS installed just to get access to the npm package manager, the Node package manager and you can install NodeJS at Node.js.org. And of course we'll need some kind of editor. I'm going to be using Visual Studio Code, but any editor will do. To get Code you can visit code.visualstudio.com. In order to get a development system up and running quickly, we're going to need webpack, but this will be installed by npm so you don't need to download it here, but you can visit webpack.js.org to find out more about the webpack technology and how it works. There are also Pluralsight courses on webpack you can look at. And here at GitHub and we're looking at a project called webpack-starter by the user wbkd. This is a seed project that's going to get us up and running very quickly. We'll use it to set up our development environment and it will allow us to test our JavaScript programs very quickly. In the next clip I'll clone this repository, but if you don't have git, you may need to download it. Git is already installed on most systems, but if you haven't installed it you can visit git-scm.com and if you don't want to use git to clone a package you can click the button here to download it, but we'll take a look at that in the next clip. Setting up a Development Environment Let's get our development environment set up. I'm here at the GitHub repository we were just looking at, webpack-starter by wbkd and I'll go ahead and I'll hit the Clone or download button and I'll copy the URL and I'm at a terminal, I'm on a Mac and I'll enter git clone and Command+V to paste that URL. So now that's cloned. We can visit webpack-starter and if we look at the files here you can see we have a package-json file. So let's go ahead and install all the Node packages we're going to need. Make sure you install Node and the npm package manager and I'll type npm install. So that installed fine and I'll go to Visual Studio Code. I'll hit Command+O to open up that folder where we just installed the GitHub project and we can see our package-json file right here and if we open up Node modules we can see that it did install a huge list of Node modules that we're going to need. I'll go to the src folder and I'll go to scripts and let's look at index.js. This is where we'll be doing most of our coding during this course. Let's just create a dummy program, a Hello World application. We have some working code now, but we need to kick off the webpack dev server. That'll be the development web server that we'll use to view our code. I'll make sure our program is saved by typing Command+S and then I'll pull up a terminal window. I'll type Ctrl+backtick and here's our terminal here. You can also pull up this window by choosing View Integrated Terminal from the menu and from this terminal we want to start the webpack dev server. So I'll type npm run dev. That pulls up our browser and I'll just click Inspect to pull up the console. Here's the console here and you can see that we are getting the message Hello World. So throughout most of this course we'll be doing our editing here and we'll want to see live refreshes in the browser. So I'll resize Visual Studio code and I can hide the Explorer here and I can close our terminal. So in most of this course we'll be looking at the console to get output from our code. And let's make sure we get live refreshes. I'll add a bunch of exclamation points and save it and as soon as I save it, our application rebuilds and it automatically refreshes in the browser. So that'll save us a lot of time when we're working with code. You just have to remember to always save your source code. If you jump from file to file you need to save each one. There's just one more thing we need to do to set up for this course. I'll open up this webpack folder here and we'll take a look at the webpack.config.dev.js file. If we look at this code right here, we can see that it uses something called the Babble loader and what that does is it converts all of the JavaScript file down to an earlier version of JavaScript, version 5 and we don't want that for this course. So I'm going to comment out these three lines. I'll hit Command+/ to comment everything out and if you wanted to use Babble that's fine, but there are a few features that won't work using Babble. Babble only converts about 70% of modern JavaScript features down to ES5. So I'll make sure I save this, hitting Command+S and I'll pull up our index.js file and this is where we'll be doing most of our coding for this course. So we're already to go. In the next course module we'll start looking at JavaScript syntax and features. Language Features Introduction Welcome to this module titled JavaScript Language Features. My name is Mark Zamoyta. In this module we'll cover some features of JavaScript that I didn't get to in my JavaScript: Getting Started course. Some of these features are relatively new to JavaScript and other features are just beyond the getting-started level. Let's take a look at what they are. We'll start off by looking at constants where we can declare symbols whose values cannot change. Next we'll look at the difference between the let and var keywords when we declare variables. We'll take a look at rest parameters. A rest parameter can collect up arguments and we'll look at destructuring. We can take an array and easily assign the elements of an array to variables. Likewise we can take an object and easily assign the properties of an object to variables. Next we'll look at spread syntax. That's a way of taking an array and spreading it out into its elements so that they can use it as parameters. Rest parameters and spread are opposite and we'll see that in the upcoming videos. Next we'll take a look at the built-in typeof function in JavaScript to get the type of a variable or constant or a literal. Next we'll look at common type conversions. Mainly this deals with converting from strings to numbers or any variable to a string. Finally we'll take a look at controlling loops. We'll see how we can break out of a loop or continue through a loop without executing the complete body. So let's get started and look at constants. Constants The value of a variable can change during the execution of a program; however, sometimes we want to use a symbol that won't change and that type of symbol is called a constant. Here's how we declare a constant. We use the const keyword for constant and it looks a lot like a variable declaration. The constant is called carId and we're initializing it to 42 and one of the rules about constants is that it must be initialized. Here we're trying to create a constant called bodyStyle, but that will generate an error. Unlike a variable a constant needs to be initialized and in this example we have a constant carId set to 42, but then later on in the source code the developer tries to assign the value 100 to carId and that will generate an error. A constant can't be changed. It can only be initialized. So here's the development environment we set up in the first module. I have Visual Studio Code running on the left side and we're working in the index.js file and on the right side we have our browser. Let's pull up a terminal quickly, Control+backtick on a Mac, and let's start our development server, npm run dev. And in our browser I'll open up the console and this is where we'll log our output. So let's create a constant. Use the const keyword. We'll name it carId and let's see what happens if we don't initialize it. I'll save the file and we get an error. We get an unexpected token after carId because we need to initialize a constant. We'll initialize carId to 100 and save it and now everything's fine. If later on in our code we try to assign a value to carId, you can see we get an error. CarId is read-only. So why would you want to use a constant instead of a variable? The key reason is to avoid programmer error in the future. If a value shouldn't change it should be declared as a constant. So that's a pretty simple concept. In the next video we'll take a look at declaring variables with the let or var keywords. let and var for Variable Declarations Let's take a look at the let and bar keywords for variable declarations. If you saw my JavaScript: Getting Started course here on Pluralsight I primarily used the let keyword, but you can also declare variables with the var keyword. Let's see the difference. So here we're creating a variable called carId using the let keyword and we're assigning 42. Now if we try to reference carId before we declare it, we get an error and that makes total sense. Programs execute from the top to bottom and we're trying to use a variable that isn't declared yet. However, now we're declaring carId using the var keyword and if we try to access carId, we do not get an error. CarId will be undefined and this is very strange behavior to people who come from programming languages such as C, C++ or Java and that's one of the reasons why the let keyword is preferred over var. Another difference between let and var has to do with scope. Here we have a code block for our if statement. The code block is between the curly braces. We're declaring a variable called foo, initializing it to 9, but then outside of that block we reference foo and that's fine. We get the value 9, but let works differently. Now in our code block we're using the let keyword. So the variable foo will only exist within that code block. Let has block scoping. Once program execution leaves that block, the variable foo no longer exists so when we try to log it out we get an error. So it's very important to keep in mind that let has block scoping and var doesn't. Let's see this in a demo. We'll use var to create a variable and let's try to access carId before it's declared. I'll save it and we get undefined. Now if we use the let keyword instead of var, I'll save it and you can see we get an error. CarId is not defined and that's actually the preferred behavior. If a developer starts using variables before they're declared we want an error to be thrown. So that's why it's a best practice to use let over var and let's also take a look at using block scope. If we create a block we'll use the let keyword to assign 100 to carId. I'll save it and for line 5 we get carId is not defined. So carId only exists within this if block. If we use the var keyword instead of let, I'll save it, and we get the value 100. There's no error thrown. So those are the two main reasons why let is preferred over var. Let helps you catch errors earlier as you're coding because the compiler will complain if there's a problem with your code. In the next video we'll take a look at a modern feature of JavaScript called rest parameters. Rest Parameters Rest parameters is a modern feature of JavaScript that allows a function to store multiple arguments in a single array. Let's see what I'm talking about. We have a function called sendCars and you'll notice this … syntax. That creates a rest parameter called allCarIds and allCarIds will be an array. If you see here where we call sendCars we're passing it three integers for carIds so these arguments will get stored in the allCarIds parameter as an array and within this function we're calling foreach on the array and we simply log out each id and we'll learn more about foreach on an array later in this course, but for now just know that we're going to iterate over the array and execute this code here, console.log id, and the result is 100, 200, 555. So again we can send any number of arguments to a function and use a rest parameter to collect them up. Let's see another example. Looking at sendCars now it has a normal parameter called day and then we have a rest parameter. So you can mix up normal parameters on the rest parameter, but you just always need to list the rest parameter last. When we call sendCars we pass it Monday and then our list of car ids, which will all get stored in allCarIds. We're not printing out day, but we will log out the car ids, 100, 200, and 555. And this is how rest parameters gets its name. It refers to the rest of the parameters or the remaining parameters. Let's see this in a demo. Here's our sendCars function with a day parameter and a rest parameter called carIds and we'll simply print out each car id. We'll call this function passing Monday and then the values 1, 2, 3. I'll save the code and the values 1, 2, and 3 are logged. So what would happen if we accidentally left out that day parameter? I'll save it and now you can see that Monday becomes part of the array, which would be a bug and what happens if we added a normal parameter after the rest parameter? I'll put day after carIds. And we get an error, Comma is not permitted after the rest element, and that make sense that the rest parameter must be the last parameter in the list. In the next video we'll take a look at another modern feature of JavaScript called destructuring. Destructuring Arrays We just saw how to build up an array as a rest parameter and there's another modern feature of JavaScript that allows us to easily assign the values within an array to variables. This is called destructuring arrays. We could also destructure objects, but we'll see that in the next video. We have an array called carIds and we'll initialize that, but here's the new destructuring syntax. You'll notice we have the let keyword. We're going to declare three variables; car1, car2, and car3, but they're in square brackets. Because the square brackets are on the left side of the equals sign that means that destructuring is going to take place. So because carIds is an array the first element of the array will be stored in car1, the second element in car2, and the third element in car3. So when we log out these three variables, we get 1, 2, and 5. So again when we destructure an array, we're taking the array and we're assigning it to variables in a short concise syntax. Let's look at another example. We're initializing carIds to the array of 1, 2, and 5, but now we're declaring two variables, car1 and remainingCars and notice that we're not initializing them yet. In the next line you can see the square braces on the left side of the equals sign, which gives us the hint that we're destructuring. So we're taking carIds and the first element will get stored in car1, but notice this rest parameter syntax. Now remainingCars will hold the rest of the ids, which will be 2 and 5. So this is very similar to what we saw in the prior video on rest parameters, except now we're using destructuring. If we log out car1 we get 1, and if we log out remainingCars we get the array of 2 and 5. Let's look at one more example. We set up our carIds and we declare remainingCars, but we don't initialize it, but now we have a comma at the start of our destructuring syntax and that simply will skip the first element. You can have as many commas as you'd like, to skip as many elements as you'd like, but notice that the remainingCars will get populated with any remaining array elements. When we log out remainingCars we get the array of 2 and 5. So because of the comma, the value 1 got skipped. Let's see some of this in a demo. So let's initialize carIds to 100, 200, 300 and we'll destructure carIds into the new variables car1 and car2. Then we'll log those out. I'll save it and we get 100, 200. Notice that 300 gets lost. Here we're only pulling out the first two values. We can go ahead and use the rest syntax here to get the rest of the carIds and we'll also log out the rest. I'll save it. Now we get 100 and 200 and the rest is an array holding the single element 300. And as we saw in the slides it doesn't always make sense to declare and initialize these variables at the same time. So let's take out our destructuring from the declaration. So we'll have car1, car2, and the rest and we'll do our destructuring on a separate line. It just may be that you need some time for data to arrive and you just can't declare and initialize these variables at the same time. So I'll save this and we get the same result, one-hundred, two-hundred, and then the array which has the single element 300 and if we left out car1 and started this with a comma, car1 will just get skipped. I'll save it and we get undefined when we log out car1. Car2 is 200 and then our array which has 300. So destructuring is a very quick way to assign array elements to variables. You can assign multiple variables usually in a single line of code. In the next video we'll take a look at destructuring objects. Destructuring Objects Let's take a look at destructuring objects. This has a slightly different syntax that destructuring arrays. We'll create a simple object called car, setting id to 5000 and style to convertible. Then we'll create two variables, id and style, and notice the destructuring syntax for objects. Instead of square brackets like we used on arrays, we're working with objects so we use curly braces to destructure an object. We'll take the id value of car and that'll get assigned to the variable id. Likewise the style property of car will get assigned to the variable style. We log out id and style and we get 5000 convertible. So again, if you're destructuring arrays be sure to use square brackets. If you're destructuring objects, be sure to use curly braces. Let's look at another example. So we have our car and we're declaring id and style, but we're not initializing them yet. We want to initialize them later in the code. So we use the curly braces specifying the id and style variables equal to car. So this looks like it should destructure into id and style, but we get an error. The reason we get an error is that is that the curly brace is also used for code blocks so the compiler is confused. Are we starting a code block or are we trying to destructure an object? So in this case we have to do something slightly different and here's the solution. We put the destructuring statement in parentheses. That solves the problem. We log out id and style and we get 5000 convertible. So we don't have this problem with destructuring arrays and we also don't have the problem if we're declaring and initializing variables at the same time, but in this case where the destructuring comes after any declaration, we need to use parentheses. Let's see a demo. So here we have our car variable. It's an object with an id and a style and we destructure car into two new variables, id and style. We'll log out id and style. I'll save this and we get 5000 and convertible. Let's not initialize our new variable's id and style and let's attempt to do the destructuring later in the code and you can see from the red squiggly that we will get an error if we try to execute this. I'll save it and we get our unexpected token error. Let's surround this with parentheses and I'll save it and everything's fine. Five-thousand convertible. So just remember to use the square brackets for destructuring arrays and use the curly braces for destructuring objects. In the next video we'll take a look at spread syntax, which is actually the opposite of rest. Spread Syntax Let's take a look at spread syntax. This allows us to take an array and spread out its elements so that they can be assigned to parameters. Here we have a function startCars. It's pretty straightforward. It accepts three cars and logs them out, but then we'll declare a carIds array and initialize it. We'll call startCars and we'll use spread syntax … along with our carIds array. So this looks very similar to the syntax for rest parameters, but the opposite is happening. In this case we're taking an array and we're breaking it out into car1, car2, and car3. When we log those out we get the values 100, 300, and 500. So while rest parameter collects up elements and stores them in an array, the spread syntax is the opposite. It takes the carIds array and spreads it out into various parameters. Let's see another example. Here we have the same startCars function, but we're declaring a variable called carCodes assigning it a string, a b c. In JavaScript both strings and arrays are called iterables. You can iterate through the elements of an array or you can iterate through the elements of a string and we'll cover iterables later in this course, but for now let's see what happens when we use the spread syntax on an iterable string such as a b c. We call startCars … carCodes and we'll break up the string a b c into the values a, b, and c, and that's what prints out. So the spread syntax is good for arrays or strings and other iterables that we'll see later in the course. Let's see a demo. We have our function startCars that'll accept three cars and we take the array 1, 2, and 3 and that gets assigned to carIds. We'll execute startCars using the spread syntax on carIds. So the first element will get stored in car1, the second element will get stored in car2, and the third element in car3. I'll save it and we get the values one, two, and three printing out. So spread syntax is the opposite of the rest parameter we saw earlier. With spread syntax we take an array and break it apart into parameters. What if we had a few more elements in carIds? We'll just add 4, 5, 6, and let's add a rest parameter to startCars, … rest and we'll just print out rest. I'll save this and we get the three elements 4, 5, and 6. So you can use spread and rest at the same time. Even though they share the same syntax they do the opposite, depending upon the context. Now because JavaScript has dynamic typing where the type of a variable can change over time, and also because we are now using rest parameters, it's often important to find out the type of a variable. So in the next video we'll look at the built-in function typeof to see how we can get access to type information. typeof() Typeof is a built-in function in JavaScript. It helps us find the type of a variable, constant, or literal value. Let's take a look at it. So for the typeof function let's pass it a number 1. That'll return the string number and that's straightforward. If we pass the value true to typeof we get the string Boolean. So true or false will result in Boolean and when we get a type of a string in either single quotes or double quotes, it returns the string string. And here let's declare a function and pass that function to typeof. It returns the string function and this is very valuable, especially if you're writing some kind of API or library. If someone passes a value to you, you definitely want to make sure that it is a function before you try to execute it. So checking if something is a function can be very valuable and here we're creating an empty object and passing that to typeof and we get object. And what about typeof null? We actually get object and this is very controversial. Many people think it should return null as the type, but it seems to be rooted in the old C or C++ days where null referred to a null object, but just keep in mind if you're looking for null values, typeof null is object and typeof undefined is undefined. That makes sense. And for the last one, which is also controversial, what is typeof not a number, NaN? Well that's actually a number and the way to make sense out of that is some kind of numeric operation went bad and you're expecting a number. So even though it's called not a number, the type is number. I don't be doing a demo with these because they're pretty straightforward, but if you ever need to know the type of a variable, constant, or literal value, just go ahead and use the built-in typeof function. In the next video we'll take a look at how we can convert from one type to another type. We'll look at some common scenarios for that. Common Type Conversions We often need to convert from one type into another type and there are several common ones that we use all the time. Let's take a look. So how do we convert any object or variable to a string? Well we can take the variable or constant and call its toString method and that's very straightforward and used often, but if we want to convert a string to say an integer? We use the built-in number object and there's a method on that called parseInt for parse integer. We're passing it a string 55 and the result is a number, 55 as a number. And what if we add a string, but we wanted to convert that into a float? Again we use Number.parseFloat, passing it the string. In this case we'll get 55.99 as a number and there are many other types of conversions you may want to do, but I found these to be the most common. Let's do a quick demo and see them in action. Let's parse an integer. We'll execute Number.parseInt and we'll pass it the string 55. I'll save it and we get the integer 55. If you want to be sure about that we can use typeof. I'll save it and we get number. Now what if we had extra characters in our integer? Let's say instead of 55 it was 55ABC. I'll save this and we still get 55. So as soon as we run into a character that's not part of the integer, parseInt stops parsing and we take what we've got, 55. Likewise if we call parseFloat and we'll say 55.88ABC, I'll save this and we get 55.88. What happens if we had extraneous values at the beginning like ABC before our 55? I'll save this and we get NaN. So would we call parseInt or parseFloat on number? We just need to make sure that it actually starts as a number. It doesn't necessarily need to end as a number. So that's all we have for converting types, but in the next video we'll take a look at some of the advanced features of loops. Controlling Loops If you've seen my JavaScript: Getting Started course or some other introductory course you should already know about for loops and while loops. But there are a few other things I want to cover concerning loops to make sure we can control them properly. So here we have an example for loop and the first thing I wanted to point out is this strange syntax here. We're not initializing any variables and that's not a requirement. We can leave the initialization out, but we do need to keep our semicolon there. So in this loop we actually initialize i before we get to the for loop. So i will be 0 and will loop while i is less than 12 and for each iteration of the loop we'll increment i by 1. Within the loop we have an if statement; if i is equal to 8, we'll execute a break statement and break will let us exit a loop. Now in normal circumstances you would want to run all the way through a loop, but in special circumstances you may need this break statement to get out. And when we do break out we jump directly to the end of the loop and we'll execute console.log i and i will have the value 8 because we exited the loop early. Let's see another example. Here i will be 0. We'll loop while i is less than 4 and we'll increment i for each iteration. Within the loop if i is equal to 2 we'll execute a continue statement and continue will let us continue the loop. No more code will execute within the block. The next thing to execute will be i++ and then the condition will be matched and we'll go from there, but when this continue executes, console.log i will not execute. So when this loop runs we get the values 0, 1, we skip 2, and 3 prints out. So remember you use the break keyword to break a loop and finish it off and the continue statement will act as if the body has finished execution. So it'll increment 1 and check the condition. Let's see these in some demos. So we have a for loop. We'll let i=0 and while i is less than 5 we'll execute the code block and when the code block completes we'll increment i. In the code block we'll log out i and if i is equal to 3, we'll break out of the loop. I'll save it and we get the values 0, one, two, and three. It'll skip 4 because of the break. Let's try a continue statement now. I'll move our logging statement. So we'll loop from 0 and i is less than 5 so we'll loop from 0 through 4. If i=3 we'll continue and we'll log out i. I'll save this. We get 0, 1, 2, and 4. So when i=3 we ran the continue statement so i incremented and i was still less than 5; it was 4 at that point and that's why we got our 4 to print out, skipping 3. So break and continue are very valuable, but you want to try to use them as little as possible. Only use them if they're necessary. And you can use them in while loops, too. They're not just meant for for loops. So that's all we're going to cover in this module. Let's wrap it up with the summary. Summary In this module we looked at constants. We saw how we can use the const keyword const to declare and initialize a symbol to be used as a constant. We took a look at the difference between the let and var keywords when we declare variables. Next we looked at rest parameters and in our parameter list we would use … and some identifier. In this case the rest will be an array holding the rest of the arguments. Next we looked at destructuring. We can destructure an array and we use square brackets for that. In this example arr is an array and the variable a will be assigned array element 0 and the variable be will be assigned array element 1. We can also destructure objects, but we have to be careful and use parentheses as needed so that the compiler doesn't get confused thinking that there's a code block where we're actually destructuring. So we use curly braces around the variables a and b and object.a will be assigned to variable a and object.b will be assigned to variable b. We looked at spread syntax which is the opposite of rest. When we call a function and we want to pass parameters to the function, we can take an array and prefix it with the spread syntax … . So the array will be broken down into its elements and assigned to parameters. Next we looked at the built-in typeof function to get the type of a variable, constant or a literal and we took a look at some of the common type conversions. We can call toString on just about anything to get a string value from it and it's very common to want to get an integer from a string. So we call number.parseInt passing it the string we want to parse. It'll return a number and to parse a float we call number.parseFloat passing it a string. We wrapped up the module by looking at how we can control loops. Whether you have a for loop or a while loop, we can break out of it and stop execution altogether immediately. We could also continue the loop which means stop executing the body, but go ahead and continue as if the body had completed. So that wraps up this module on language features. In the next module we'll take a look at many of JavaScript's operators. Operators Introduction Hi. My name is Mark Zamoyta and welcome to this module titled Operators. By operators we mean the simple mathematical operators plus, minus, multiply, divide, that kind of thing, but there are actually many more different types of operators. Let's see what we'll cover in this module. We'll start off by looking at equality operators, comparing if two numbers are equal or unequal. We'll look a unary operators. Those are operators that work on a single value or variable. Logical operators are also sometimes called Boolean operators and they result in a true or false value. Relational operators are things such as greater-than, less-than and so on, but we need to look at how relational operators work with strings. We'll take a look at the conditional operator, which is a shortcut for an if statement, an else clause, and we'll look at assignment operators. These are shortcuts which let us easily modify a variable in a concise syntax. Finally we'll take a look at operator precedence and this is very important. We know that operators such as multiplication come before addition and not knowing that rule is the cause of many bugs. So we'll take a look at the Mozilla developer network where we can find a table of operator precedents that can be used as a reference as we code. So let's get started and look at equality operators. Equality Operators We'll start off by looking at the equality operators. These operators let us compare two values to see if they're equal. They're also inequality operators which let us know if two values are not equal. So here we have the double equals sign. If variable 1 and variable 2 are equal the code block will execute and the important thing to note here is that JavaScript is going to attempt to convert these variables to be the same type. If you had a number and a string, it would try to convert the number to a string to make the comparison, but here we have a triple equals sign and this will not do the type conversion. The types of the variables have to be equal as well as the values for this to be true. Sometimes the symbol is referred to as the strict equality operator or you could say something like variable 1 is identically equal to variable 2, but it's very important to notice the difference between the double equals sign and the triple equals sign and the best practice is to use the triple equals sign whenever possible. This will just help us make sure that our variables are the correct types. Now we also mentioned the inequality operators. Those would be not equal to and not double equal to. Again not equals will try to convert the types to be the same and not equal equal is not identically equal to; that won't do any type conversion. The types of variable 1 and variable 2 must be the same. So let's look at these operators in action. So if we do something simple such as 1 == 1, I'll save it and you can see we get true. Normally these operators would appear in if statements or while loops or other places where you expect conditionals, but for now we can just log them out to the console and what if we say 1 == true, the Boolean value? Again that's also true. Now to test this out with the triple equals sign, now we have 1 is identically equal to true. I'll save it and now it comes up as false because 1 is typed number and true is a Boolean type. So it's very important to keep in mind this difference. And of course this works with variables as well. We'll let id = 123 and that'll be a number and let's compare id with the string 123. And again we have the is identically equal to symbol, triple equals sign. I'll save it and we get false. If this had been a double equals sign, I'll save it and we get true because it does do the type conversion to a string. If we look at the inequality operator, not equal to, you can see that this is false. Because they are in fact equal to each other. If we add in another equals sign, is id identically equal to the string 123? Well it's not. Id is typed number and string 123 is a string. When I save this, we get true. That's correct. So it's very important to keep in mind the difference between the double equals sign and the triple equals sign and its counterpart, the inequality operators. In the next video we'll take a look at unary operators. Unary Operators Let's take a look at unary operators. These operators operate on a single value or variable. The double plus sign increments a variable. So if var1 was equal to 5, after this executes var1 would be equal to 6. We can also place this operator after the variable name. Variable 1 will get used in some kind of expression and it will only get incremented after its use, but with ++var1, var1 will be incremented before it gets used in an expression and we'll see an example of this shortly. Likewise we can have --var1. The -- is the decrement operator which will subtract 1. Likewise we can have that operator after the variable. Another unary operator is the + symbol. That's not used often, but it could convert a string into a numeric type and the - operator changes the sign of a numeric variable. If var1 was -5 it will now be 5. And we'll see an example of that as well. So here we have a variable called year and we're setting it to 1967. What if we log out ++year? I'll save it and we get 1968. So it added 1 to year and then logged it out, but if we placed the ++ symbol, the increment operator after the variable, I'll save this and it prints out 1967. So the variable year was used and only after it was used in this expression was it then incremented. If we log out year next, I'll save it, you can see that the first log statement resulted in 1967, but year was incremented. Year was set to 1968 at the end of this program. So it's very important to keep in mind whether this operator comes before variable or after the variable and the decrement operator works much the same way, only it subtracts 1 from the variable. Let's look at the + operator. If year was actually a string here and let's print out the type of year, you know type of year would be a string as it is here. We get string, but if we added a + symbol to it, we get the conversion and it becomes a number and it's important to note that this + symbol does not make it positive. If this were a negative year, I'll save it and we still get a number, but let's see what value we get. We still get -1967. If we wanted to negate a variable we would use the - sign. I'll save it and now we get +1967. If 1967 as a string were positive, now we get the opposite, -1967. So again these unary operators operate on a single variable or a single value. In the next video we'll take a look at logical operators. Logical (Boolean) Operators Let's take a look at logical operators. These are also called Boolean operators because they result in a Boolean value, which would be true or false. The first logical operator we'll look at is the & symbol right here, double ampersand. For this if statement to be true, both expressions need to be true. So the code block will only execute in the circumstance. Var1 needs to be greater than 5 and var2 needs to be less than 100. If one of those is false the code will not execute. And this double pipe symbol is the logical or operator. Only one of these conditions needs to be met for the code block to execute. Either var1 has to be greater than 5 or var2 needs to be less than 100. So either one expression or both expressions need to be true for the code to execute. And here we have an example where we're using the or symbol as well as the and symbol and you have to be very careful when doing this because the and symbol has a higher precedence. So these two expressions here will be evaluated before the or symbol and this is a very common source of bugs. If you intended for the or operator to kick in first, you have to do something like this and surround the or conditions with parentheses because putting something in parentheses has the highest precedence. And we'll cover precedence later in this course module, but I need to point this out now because it is such a common bug. A logical and has precedence over a logical or. We can also use these logical operators outside of a conditional. If we say var1 and var2, the result will be var2 if both of these objects are truthy and we'll see an example of this shortly. And here's a much more common use of logical operators. It's the logical or with two variables. If var1 is a valid object the result will be that. If var1 is falsy such as being undefined or null then var2 will be the result. And again that's very common to use this logical or in this way. We'll see a good example coming up. And the final logical operator is the not symbol, the exclamation point. This will convert var1 into a Boolean value, either true or false and then flip it. So if var1 is a valid object, well that results in true, but the not symbol will make this expression false. Let's look at some examples. Let's look at this conditional. If 5 is identically equal to 5 and 6 is identically equal to 7, we'll log out true. Otherwise we'll log out false. I'll save this and execute it and of course we get false. Both expressions need to be true in order for the full condition to be true. I'll save this and now we get true. Again if this was a logical or I'll add the pipe symbols. This is true as well, but if both of these expressions are false, I'll save it and the result is false. And let's look at another common example of the logical or, but used with variables. So let's say we have some user settings which are null and we have some default settings which have valid values there. The common usage is to check the user settings and if that's truthy, we would log out that, but if user settings is falsy, something like null undefined 0, then the logical or would make sure that we used the default settings. So I'll save this and you can see that we do get the default settings here because user settings is null, but what if this were a function and someone did pass in valid user settings? So now the user settings are set. I'll save it and you can see the object we get is the Joe object, our user settings. And this is something you see all the time in JavaScript. It's used not just for settings, but for default values and any situation where an argument to a function may be null or undefined. And much less common is the logical and used in this way. If the and is used it'll test user settings; that'll be true, but it will also check the default settings and take those. I'll save this and we can see what we get. We get the default settings. So it's much more common to see the logical or in situations like this and finally the not symbol. If we log out not true, we get false. If we have a variable we'll set car to null and we'll log out not car. I'll save it and we get true. Because car on its own is false and with the not symbol it becomes true, and this would mostly be used in something like an if statement. If not car then you probably want to set car to something valid. So that's all we have for the logical operators. In the next clip we'll take a quick look at relational operators. Relational Operators Let's look at relational operators. These are covered in my JavaScript: Getting Started course and most beginner-level courses will review these. The relational operators are greater-than, less-than, greater-than-or-equal-to, and less-than-or-equal-to. And those are straightforward in their use for comparisons. Comparing numbers is easy, but the problem comes with strings. Here we have the string Zoo with a capital Z, less than the string alphabet with a lowercase a and you would think that this expression would result in false because a comes before z, but unfortunately the result is true. All of the uppercase characters are considered less than all of the lowercase characters. It's compared by ASCII value and you can look up an ASCII table to see that for yourself, but let's see a common way to get around this. Here we have string 1 and string 2 set to Zoo and alphabet. Zoo is capitalized. So if s1 is less than s2, we'll log out true otherwise false. I'll save it. And we get true because uppercase letters come before lowercase letters. And one common way to fix this is with the toUpperCase function. We could also use the toLowerCase if that's what you wanted to do, but we'll convert both of these strings to uppercase. And I'll save it and now we get false. If the strings are converted to uppercase alphabet does come before Zoo. So just be aware when using these relational operators, if you're working with strings you have to keep the case in mind. In the next video we'll take a look at the conditional operator. Conditional Operator JavaScript has a conditional operator which can be used in place of an if statement. Let's look at it. The conditional operator has a few different symbols. It starts off with a conditional and the parentheses are optional, but they're usually added to make it more clear that we are dealing with a conditional and that's followed by a question mark. So if the condition is true we use this expression here. That's followed by a colon and if the expression was false we use this expression here. Let's see this in action. So our condition is 5 is greater than 4, then the ? and then the true value. We'll use yes as a string. If the condition we'll log out no as a string. I'll save this and we get yes, the true expression. If we change the 4 to a 44, I'll save it and we get no. And as I mentioned, these parentheses are optional so I'll just take them out and the spacing is optional as well. You don't need spaces around the question mark or the colon. I'll save this and we get the same result no. So if you have a simple if statement with an else block, using the conditional operator here is an easy way to accomplish the same thing. In the next clip we'll take a look at assignment operators. Assignment Operators Next we'll take a look at JavaScript's assignment operators. So we take an operator such as + and put an = sign after it. So this line is equivalent to var1 equals var1 + 10. It simply adds 10 to var1 and stores it back in var1. Likewise we can do the same with subtraction. This will subtract 10 from var1 and save it in var1. We did the same with division, multiplication, and the remainder operator. This is also called the modulus operator which gives a remainder and there are a few other assignment operators which are less commonly used. This is a Shift+Left operator. It'll take var1 and shift its bits to the left by 1 bit. So this mainly works with integers or bit fields and it's not very common. If you wanted to shift the bits to the right, you use this operator and if you wanted to shift the bits to the right, but keep the sign, you would use three greater-than signs and an equals sign. And if you're not used to working with bits, don't worry about it. These are advanced operators. Let's see some examples. So we're setting year to 1964 and logging it out. Let's use some assignment operator. Year += 10. I'll save it and we get 1974. If we use -= 10 we get 1954. Likewise we can use division, multiplication, modulus and bit type operators. This wouldn't be too useful for a year, but if we shifted it right let's say 1 bit, that's equivalent to dividing it by 2. I'll save it and we get 982. If we shifted it to the left by 1 bit, that's the same as multiplying it by 2. I'll save it. We get 3928 and there are other Boolean operators that you could use here as assignment operators, but that's beyond the scope of the course. You can check out the Mozilla developer network to work with the and, or, or exclusive or bitwise operators. And that's all we have for operators, but I do want to discuss operator precedence, which we'll look at in the next clip. Operator Precedence Operator precedence refers to the order in which operators get executed and as I've discussed already, this is the source of many, many bugs. Let's go to the Mozilla developer network and see a table which helps us clarify operator precedence. So I went to developer.mozilla.org and I searched for operator precedence. I'll click on the table link and here we have our precedence table. At the very top you can see that we have parentheses. Parentheses have the highest precedence and will always be evaluated first. Another thing that we looked at in my JavaScript: Getting Started course was the fact that multiplication takes place before addition. Let's look at that. I'll scroll down and here we have multiplication at level 14 and we have addition at level 13. So no matter what order we add and multiply numbers, the multiplication will always execute first. We also looked at our logical operators; let's find those. And here we have them. At level 6 we can see that a logical and, the two ampersands, takes precedence over the logical or and I pointed this out back on the clip on logical operators. So this chart is invaluable. If you ever have a question about which operator takes precedent over which other operator, this is where you come. You go to MDN and you search for operator precedence and find the table. Let's wrap up this course module with a summary. Summary In this module we looked at the equality operators. Those are double equals, triple equals also known as identically equal to, and then not equal to and not double equal to. We saw that the triple equal sign as well as the not double equals sign do not perform a type conversion. If you're comparing values of different types the result is false. We looked at unary operators. Those are plus-plus to increment a variable, minus-minus to decrement a variable, plus which is usually used to convert a string to a number, or minus which flips the sign on a number. We looked at logical operators, also called Boolean operators and those are and, or, and not. And it's important to know that and takes precedence over or. We looked at relational operators. For strings you need to keep in mind that capital letters come before lowercase letters in the ASCII table and the way to get around this is to convert your strings to uppercase or lowercase before using a relational operator on it. We looked at the conditional operator. We have a condition, which we usually put in parentheses, the question mark, our true-value : false-value. This is a shortcut for an if statement. And we looked at assignment operators. Those are +=, -= and any other operation followed by an equal sign and we also saw some operators that work with shifting bits such as less-than-less-than-equal-to to shift the bits left and greater-than-greater-than-equal-to to shift bits right. We wrapped up the module by looking at operator precedence. We saw how to find the precedence table on Mozilla developer network and we saw how it could be used when we're unsure about precedence. So that wraps everything up for operators. In the next module we'll take a look at functions. Functions and Scope Introduction Welcome to this course module, Functions and Scope. I'm Mark Zamoyta for Pluralsight. Let's see what we'll be covering in this module. We'll start off by looking at function and block scope. Block scope wasn't available in JavaScript until recently with the ES2015 release of JavaScript. So we'll take a close look at that. Next we'll look at IIFEs. IIFEs are immediately invoked function expressions and we'll see that pattern and we'll see why it's used. We'll look at closures. A closure is a function and its context that are kept around in memory. We'll see why this is important. We'll look at the this keyword. Every function has a special keyword called this, which refers to the function's context. We'll learn all about it. And there are three special functions that can be called on other functions; call, apply, and bind. These all have to do with the this keyword. Next we'll cover arrow functions which is a new concise way of declaring a function and we'll wrap up this module by looking at default parameters. That's another new feature of ES 2015. So let's get started and take a look at function scope. Function Scope When we talk about function scope we're talking about variables that can be accessed within a function or nested functions and it's important to know the lifetime of these variables. Let's see some examples. Here we have a function startCar, which simply declares a variable, message. We'll execute startCar, but then we'll try to access that variable message. If we do this we get a reference error and that's because this variable message has function scope. As soon as this function finishes executing, message is no longer available. So you would say we'd get this reference error because message is out of scope. Here's a little bit more complex example. We have our function startCar and our variable message set to starting, but now we have a nested function. This is a function expression. We're setting the function turn key to the variable startFn for start function. And within this function we'll simply log out message. We'll execute startFn and we'll kick everything off by calling startCar, but when we get to this line, message is valid even though it's not declared in this function turnKey. If the function can't find the variable it looks to its parent function and it finds it right here. So in this case starting is logged out. It doesn't matter how deeply you have these functions nested. JavaScript will continually look at a parent and its parent and so on until it finds the variable in scope. Otherwise you'll get a reference error. And here's the final example for function scope. We have the same function startCar, we declare message and we have our function expression, but this time we're declaring a variable called message and you'll notice that this has the same name as the parent function. So when we execute startFn this message will be set to override, but then when we log out message here, we actually get the message starting. So when a nested function uses the same variable name as its parent, that's legal but it will go out of scope. So this variable message never gets changed. Let's see this in action. Here we have our first example where we have a function startCar and we're declaring the variable message, the logout message right here. I'll save this and we get a reference error. I'll increase the font size, reference error, message is not defined and the reason why is that this message went out of scope. And I'll paste in the next example. So here we have the same startCar function, but this time in the turnKey function we're going to log out message. I'll save it and we get our message starting. So turnKey does not declare a message so it looked in its parent function and found it right here. And we'll look at the final example. Here we have the same startCar function, but let's look at our function turnKey right here. This re-declares the variable message with a let keyword. So message is being set to override. We'll call startFn and then we'll log out message. I'll clear this out and resave it and we get the message starting. So this message went out of scope, but when we logged that message our original message was in scope, that's why we get starting. So you always need to be aware when variables go out of scope and when they come back in scope. And know that a function will look to its parent function for a variable and go on up the function chain like that. In the next video we'll take a look at block scope. Block Scope By block we're referring to a code block. That's code that's placed in between curly braces. So by block scope we're talking about the lifetime of variables as they exist within curly braces. That could be for an if statement, a while loop, a for loop, or any set of curly braces other than a function. Let's see some examples. We have an if statement. If 5 is identically equal to 5, we'll execute this code block. So inside these curly braces we declare a variable message, setting it to equal, but you'll notice that this block completes and when we try to log out message we get an error. Just like with functions we would say message went out of scope as soon as this code block finished. That's why we get a reference error. In this example we're declaring message. We're setting it to outside. We have our if statement and our code block, but you'll notice that we're re-declaring the variable message in this code block. Let message equal the string equal, and when we log out message we get equal, but then the code block completes. Now when we log out message we get the string outside. So we are allowed to reuse variable names within code blocks. They temporarily override the outside variable. Let's see this in action. We have our if statement and we declare a message. Notice we're using the let keyword. This is a relatively new feature of JavaScript. It came in the ECMAScript 2015 version. So we must use let for block scope. And when we log out message, I'll save this and we see what we get. We get the reference error. Message is not defined. And of course if we used a var here, that would get hoisted. It would essentially behave as if it moved message to the top of the file. So I'll save this and here you notice that with the var keyword we do not get block scope. It printed out equal. Let's look at the next example. So here we declare a message. We have our if statement and we re-declare message using a let keyword. So we'll log out message within this block, but then when the block completes we'll log out message again. I'll save it and we get equal for our first log statement and outside for our second log statement. So after this block you would say that message went out of scope, but this message is still in scope. That's why outside prints for the second log statement. Again this only works with let. If these were vars I'll save it. And it prints out equal and equal. There's no such things as block scope for the var keyword. It only applies to let. So to prevent this unexpected overriding, it's a best practice to use the let keyword when declaring variables. That's all we have for block scope, but in the next video we'll take a look at a pattern that's very popular; it's called the IIFE pattern. IIFE's It's very important to organize our code when we write JavaScript. In modern versions of JavaScript we have modules and we'll learn about that later in this course, but before these modules came along, we needed a way to group our code and have it work in isolation where it wouldn't interfere with other code and that's how the IIFE pattern developed. Let's take a look at it piece by piece. First of all IIFE stands for immediately invoked function expression and if we break this down a function expression is simply taking a function and doing something with it, usually assigning it to a variable and by immediately invoked, that means running the function immediately after it's declared. Let's see what we mean by this. Here's a simple function where all we do is log out a string. Now this function won't execute. It doesn't have a name and we're not doing anything to call it, but let's see how we can do that. By putting the function and its body in parentheses, here's the opening parentheses and here's the closing parentheses, by doing this we can now execute the function with our opening and closing parentheses here. So that's what we mean by immediately invoked. This function is going to be called right away and by function expression it generally means assigning this function and its results to a variable or it could be used in some other expression. Let's see an example of that. So here's our function that gets immediately invoked and we're assigning the result of this to app. App stands for application. So if you wanted to take your application and bundle it into a simple module, this is a pattern you could use. The IIFE pattern. And let's look at what this IIFE does. We declare a variable called carId and assign it 123. We'll log out the string and function and the return value of an IIFE is very important because that's what gets assigned to app, the variable. Now this IIFE is rather useless because it doesn't return anything. Generally what gets returned are functions within this IIFE and that's where the value of an IIFE comes from. It comes from creating a closure and we'll talk all about closures in the next clip, but for now let's just make sure that we can create one of these IIFEs. I'll go to Visual Studio Code. So here we have a function and it simply logs out in function. How do we turn this into an IIFE? Let's add our beginning parentheses and our closing parentheses and now we can call this function by passing the argument list. We don't have any arguments so we'll just add an opening and closing parentheses and we'll add a semicolon to show that this is an expression. And I'll save it. The function does execute and we get in function as output. Now the value of this IIFE is that it can hold on to variables when we create a closure. We haven't learned about closures yet, but let's just create a variable. We'll create carId and we'll also return an empty object, and of course we're going to need to hold on to the result that it returns. So one standard variable name, if your IIFE is related to an application, is to use the variable app for application. So here we have our IIFE. Let's just log out app. I'll save this. The IIFE executes, we get the string in function to show, and then we log out app, we do get the empty object that was returned from the IIFE. So that's all we're going to show in this clip. The real value of an IIFE is when the IIFE is used as a closure and we can access functions within that module and we'll see that in the next clip. Closures Normally when a function executes it runs through all its code and then completes. All of its variables go out of scope, all of its functions go out of scope, but sometimes we want that function and its variables and nested functions to hang around and that's what a closure is. Let's see how we can use a closure with the IIFE pattern we just learned. So here's our IIFE, we'll create a variable carId setting it to 123, and we'll create a function, assigning it to getId. This function returns carId. Now of course carId isn't declared here so it'll reach to the parent function and get carId right here. And here's how we create a closure. We'll return an object where the property is getId and its value is the function getId. We could've named the property anything, but usually you'll see the property name and the function name; they will be the same. But now this object will get assigned to app and down here we'll log out app.getId and this will return 123. Let's go to the code and walk through this a bit. Here's our code from the slide and let's see what happens when we call app.getId. I'll save it and we get 123 and it's important to know how we got this value. Our variable app gets set to the return value of the IIFE and that includes a reference to our function getId and as long as we hold on to this reference or this function, our IIFE will persist. Not only will the function persist, but its parent function will persist along with all of its variables. So when we call app.getId this getId gets executed and this carId gets looked up. It gets found in the parent function right here. So that's the value of a closure and an IIFE. Any variables declared in the IIFE will persist along with any functions. You just need to make sure that you return a reference to the function like we do right here with getId. In the next clip we'll take a look at the this keyword, which is an important keyword that we use within functions. The this Keyword There's a special keyword we can use within functions. It's called this and this refers to an object, but it doesn't refer to the function as an object itself. It's a special object called a context for the function. Let's see some slides. Here we have a function expression and in the function we're going to log out this is identically equal to window. So this is a keyword that exists within functions and window of course is our global object. Because we're not in strict mode and this is a simple program, when we execute fn for function, we get the value true. So when we're outside of strict mode and we're working with a scenario like this, the this keyword does equal the global object. That's the context of this function, but this isn't usually how we use the this keyword. Usually we're working with objects. Let's see the next slide. So here we have an object. It has a property carId 123 and it also has a property getId, which is a function. The function returns this.carId. When we log out o.getId it returns the value 123 because in this case our this keyword refers to the object that holds the function, o right here. So when we access this.carId we get carId 123. And this is the most common scenario where you see the use of the this keyword. It's in functions that our property is of an object. Let's see this in Visual Studio Code. Here's the code from the slide and I'll just go ahead and execute it by saving it and we get 123. Let's log out the value of this. I'll save it and you can see we get our carId and getId, which is a function shown as f right here. So remember that every function gets associated with the this object. The object is usually the object where the function is defined, but I say usually because functions in JavaScript can be moved around from object to object. They can have different contexts and the this value can change. In the next few clips we'll see how this can happen. call and apply Most of the time when you call a function you're going to specify the opening and closing parentheses and place any arguments there, but there are two different ways to call a function. You can use the call function and the apply function and the main purpose of these two functions is to change the value of this. That's to change the object which is the context of the function. And this is important for object-oriented scenarios. In this example we have the same object we had before in the last clip. Property carId is set to 123 and getId is a function that returns this.carId. So as it stands this will return carId 123. But now let's declare a new variable, newCar and that has carId 456. What if we wanted to execute this getId function on this newCar? And that's one of the flexibilities of JavaScript. We can take a function and change its context. Again, the this keyword is the context object for a function. So in order to call getId on newCar we'll reference o.getId, that's the function, but instead of calling that function directly, we'll call a special function called call. So we'll specify .call and we'll pass it the new context, the new value for this. So when we execute this.carId, this refers to newCar. So this.carId is now 456 and that's what gets logged out. We'll see a code example in a second, but I just want to talk about the apply function next. Apply is similar to call. The only difference is that with apply, you can pass arguments. So if we look down here we call o.getId.apply and we pass it the new value of this for the function, the new context newCar, but we also pass it an array and it's an array of arguments. We have one argument which is the string ID:. If we look at our getId function we do accept prefix now as a parameter and we've returned prefix plus this.carId. So the result of this is ID: 456. So call and apply are similar functions. The only difference is that apply accepts an array of arguments. Let's see this in action. Here's the code from the slide and when I execute it, you'll see we get ID: 456. So we called o.getId.apply and newCar became the next context for getId. So this refers to newCar. This.carId is now 456 and we also pass the argument ID: space which becomes prefix in the function. And of course if you had multiple arguments you could separate those with commas. So again, call and apply are both used to change the value of this within a function. In the next clip we'll take a look at a special function called bind, which also has to do with the this keyword. bind We saw how call and apply allow us to call a function and change the this value, but sometimes we need to make a copy of the function and also change the this value and that's what bind does. We call bind on a function and it makes a copy of that function and assigns a new context, a value that will be accessed by this. Let's see an example. Here we have the same object we've been working with. We have a carId property and a getId function property which returns this.carId so at this point it would return 123. Then we have a newCar object with carId 456, but now instead of calling call or apply we want to make a copy of this getId function and we do that right here by calling bind on getId and we pass it the next context, the new value for this which is newCar. So all of this creates a new function which we'll store in a variable newFn. When we execute newFn we do get the value 456. Let's see this in action. Here's our code from the slide. I'll save it and you can see that we do in fact get 456. So by calling getId.bind we're actually making a copy of this function and not only are we making a copy of it, but we're taking newCar and assigning it to this within the function. So keep in mind that call and apply will not make a copy of the function, it'll just call an existing function, changing this, but if you want a brand new function, which is a copy of an existing function, you use bind and pass it the value for this. So that's all we have for working with the this keyword. In the next video we're going to take a look at arrow functions and that's a new way in JavaScript to declare and use a function. Arrow Functions Traditionally we defined functions in JavaScript by using the function keyword, but in the ECMAScript 2015 version of JavaScript we now have arrow functions, which have a more concise and modern syntax for function declarations. And here we see a simple arrow function. The empty braces simply mean there are no parameters to this function and after any parameter list we use the equal greater-than symbol. That's how arrow functions gets its name, by the symbol and after that symbol we have the return value of the function. In this case it's simply the integer 123. So when we log out, getId called as a function we get 123. So this does look a little bit cryptic and it is a little bit tricky at first. Just remember we have the parameters, the arrow function symbol, and then the return value. In this example our arrow function has one parameter. Prefix. Notice that we don't need to put prefix in parentheses, but that's only if there's one parameter. The return value is prefix + 123. So when we call getId passing it ID: the result will be ID: 123. And this example has two parameters, prefix and suffix. If an arrow function has two or more parameters we do need the parentheses. The return value is prefix + 123 + suffix. So calling getId with the two arguments ID: and ! the result is ID: 123! And so far all of our arrow functions would simply return a value, but sometimes we need more complex logic in an arrow function. So here you can see that we can specify the opening and closing curly braces to get a function body. We can have as many lines of code as we'd like in here, but when it is time to return a value we do need the return keyword. We didn't need this in the previous examples. So if we call getId with the arguments ID: and ! we get the same result as in the last example, ID: 123 !. Let's see this in action. Here's the example we just saw and I'll save this and run it and we do get ID: 123 !. Because we're using a function body here with the opening and closing curly braces we need this return statement. If I take this out and save it, you can see that this arrow function returns undefined and that's not what we want at all. So if your function only has a return statement we can simply take out the code block and show the arrow function like this. So there's no curly braces and there's no return statement. I'll save it and we're back to getting what we expected. And just remember, if there are no arguments, let me take out the arguments right here, and there were no parameters, we still need these opening and closing parentheses. I'll save this and we get 123. One thing you might see is instead of this opening and closing parentheses, you'll see an underscore and an underscore usually signifies a variable and the underscore may or may not be used within the function, but it is a convention. A lot of programmers will use this underscore instead of the opening and closing parentheses. I'll save this and we get the same result, 123. So arrow functions are a way to make function declarations more concise, but there is one other important fact about an arrow function. Arrow functions do not have their own this value. This refers to the enclosing context. So arrow functions were designed to get around problems with the this value and in an upcoming module on classes we'll see how it's a good idea to use arrow functions for methods, but for now there's one recently added feature to JavaScript concerning functions which has to do with default parameters. We'll see that next. Default Parameters In earlier versions of JavaScript there was no way to take a parameter and give it a default value, but we can do that now in the ES2015 version of JavaScript. Here's an example. In our parameter list we have carId and we have city= the string New York, and this is how we set a default value for a parameter. If city is not specified as an argument, the value NY will be used. And here we see an example of interpolation. This is another ES 2015 feature. We use back-ticks around a string and we can interpolate variables here. So this will write out tracking the variable carId and the variable city. So the first thing we'll log out is trackCar 123. The 123 is the carId, but we're not specifying a city. So the default value NY will be used. In the next example we call trackCar passing it 123 and Chicago so that blocks out tracking 123 in Chicago. And just keep in mind that all of your default parameters need to be listed on the right side of your parameter list. Here carId must come first because it's an expected value. Let's go to Visual Studio Code. Here's our example and I'll save it and we get tracking 123 in New York. So here there was no city specified so city is a default parameter with the value NY. Then it shows tracking 123 in Chicago. Because we're passing Chicago there is no need for a default parameter. City will be set to Chicago. And it makes logical sense that you wouldn't have a default parameter listed first. If I swap the order of these parameters this really doesn't make any sense and we'll see what happens. CarId becomes undefined and that's not what we wanted. So that wraps up the subject of functions. Let's wrap up this course module with a summary. Summary In this module we took a look at function and block scope. By using the let keyword we can now have a block scope in JavaScript. Variables declared with let will disappear at the end of the block. We covered IIFEs, immediate invoked function expressions and we saw how they can be used to organize our code into modules. We took a look at closures and we saw how a function and its context can be kept around in memory and reused, even after a function completes execution. We took at look at the this keyword and how that's the context of a function and we saw how call, apply, and bind are used to change the this value of a function. Call is used to call a function, changing the this value. Apply is the same as call, except you can pass it an array of arguments. And bind actually makes a copy of the function, resetting the this keyword. Next we looked at arrow functions, which is a modern, concise way of declaring a function and one of the big benefits as we'll see later in this course is that an arrow function does not have its own this value. And lastly we looked at default parameters. So in your parameter list when you're declaring a function you can use the equals sign to give a parameter a default value. In the next module we'll take a look at objects and a way of grouping objects into arrays. Objects and Arrays Introduction Hi. My name is Mark Zamoyta and this module is titled Objects and Arrays. I already covered objects and arrays in my JavaScript: Getting Started course so we'll go a little bit deeper here in JavaScript Fundamentals. We'll start off by looking at constructor functions and how we can instantiate new objects. We'll take a look at prototypes. A prototype is an important property of a constructor function and we'll see how to use it and we'll see how we can expand objects using prototypes. These are sometimes called polyfills. Next we'll take a look at JavaScript Object Notation, JSON. This is a way of creating objects or arrays that can be transferred over HTTP or stored in a file. And we'll wrap up this module by looking at array iteration. Commonly for loops are used to loop through an array, but we can use methods as well and we'll see how to do that. So let's start off by looking at constructor functions. Constructor Functions A constructor function in JavaScript is used to instantiate new objects. It looks a lot like a regular function, but it behaves very differently. Let's take a look. Here we have a function called car and notice that it has a capital C. This is a convention for constructor functions. This way we can work with a car object. This function is empty now, but we'll be building on it throughout this module and in order to create a new car object we'll use the new keyword. We put new before the function call. So newCar with parentheses will create a new car object and we'll assign that to the lowercase car variable. We do have classes in JavaScript, but that came in a later edition. Constructor functions was the primary way that objects would get created and we can still use them and you see them in lots of code. So let's see how we can work with properties in a constructor function. In this constructor function we have car taking the parameter Id and we're going to assign ID to this.carId. One thing that happens when you use the new keyword is that the function gets a brand new empty context. So by specifying newCar 123 right here, this and the constructor function will be a new empty object and that's where we store the properties and functions for this object on this. When we log out car.carId we get 123. Let's take a look at a method now. Here's the same constructor function as far as the id goes, setting this.carId equal to the passed-in parameter id, but now we're setting this.start to a new function and we'll simply log out start: this.carId. So now our object has a method, start. We'll let car = new Car 123; we saw that before. So now our object, lowercase car, has two members. It has a property carId and it has the property start, which is actually a method. It's a function that we call and when we call car.start it logs out start: this.carId which is 123 and we get this result. Here we have our constructor function car and we're simply going to log out the value of this and this is the wrong way to call a constructor function. We're simply treating it as a normal function. I'll save this and we'll see what we get. The value of this is set to the global window object and that's not what we want at all. That's going to cause a lot of problems using the window object. So to create a new car object let's create a variable. We'll just call it vehicle and we'll set it to a new car. We need that new keyword used on the constructor function car. When I execute this now you can see the value of this. It's an empty object. I'll paste in a larger example. So now we're passing car and id, 123. We'll capture that id in a parameter and we'll set this.carId equal to that id and this.start will be a function, which is also called a method if it's used on an object. This new car object will be stored in a local variable called vehicle and we'll call vehicle.start. When we run this we get the message start 123. So the most important thing to keep in mind when working with objects like this and constructor functions is to use the this keyword to access the context of the object. Properties and methods should be stored on this and it's a very common bug to forget to add the this prefix to a property. If I take it out and save it, you can see the error we get. We get a reference error, carId is not defined. So I'll add it back and everything should be fine. In the next clip we'll take a look at something called a prototype, which is an important property on any JavaScript object. Prototypes The subject of prototypes is very complex so we're only going to cover the basics in this course and we'll cover the most common use for prototypes. Before we use a prototype property, let's take a look at the last slide we saw in the prior clip. Here we have our car constructor function and it has a property carId and a method start. The fundamental problem with an object like this is that if we created 100,000 car objects this function would be replicated 100,000 times because it gets created right here in the constructor function. We don't need 100,000 copies of that function. We just need one and that's where prototypes come in. A prototype exists directly on car as a function. Here you can see that our constructor function is much simpler. It only has the carId property here, but now we're working with a prototype. Car has a property called prototype and we can go ahead and add our methods directly on prototype. So here we're creating a start method. We'll set it to the function where we simply log out start: this.carId. So now we can go ahead and make a million car objects if we want to, but there will only be one function and this saves a lot of memory. The only thing to keep in mind is that we still need to work with the function's context which is this. So we reference this.carId. When we create a new car and assign it to the car variable, we can go ahead and call car.start and we get start: 123. So by working with this prototype property of car, we can add our methods directly on car and use them on any object. Expanding Objects Using Prototypes We just saw the most common use of a prototype in working with objects. And probably the second most common use of prototypes is used to expand objects and give new functionality to all instances of an object. You may have heard the term polyfill and polyfills typically use prototypes. Let's see an example. So let's start with the string constructor function. This is built into JavaScript and we can access its prototype and let's create a new method called Hello. We'll set it to this function. We'll call this.toString. That'll return the string itself, but we'll add the word hello to the end of it. So any string in JavaScript now has access to this function. We'll create a string with the content foo and we'll call Hello on it and the result is foo space Hello. So this is a way that we can take functionality and apply it to any of our own objects or any of JavaScript's built-in objects. Just make sure to use the prototype property and place the new method on prototype. JSON - JavaScript Object Notation Let's look at JavaScript Object Notation. This is referred to as JSON or sometimes people just call it Jason. Either pronunciation is okay. The purpose of JSON is to transmit JavaScript objects over the wire. Most often it would be sending or receiving a JavaScript object to some API such as a RESTful API on the web. Here we have an object literal and this is not JSON. This is JavaScript code. We simply create a variable car with two properties, id and style. If we wanted to send this object to some endpoint on the web, we would want to convert it into JSON. The way we do that is with the global JSON object right here and we can call the method stringify, passing it car. That'll take the car object and turn it into this string right here. And we can see that this string looks much like the object literal, but there are important differences. Id needs to be in quotes and style needs to be in quotes. The only thing that doesn't need to be quoted is the number 123, but now we can take this string and pass it on to some API. Here's an example of converting an array to JSON. CarIds is a new array and it has three objects in it. Each one has its own carId. We call JSON.stringify passing it the array, and this the result we get. And again, JSON looks very similar to the object literal notation. It uses the square brackets for the array as well as the curly braces for the objects. You just need to be sure that any string is quoted. Let's take a look at parsing JSON. JSON would come in from a web server or some kind of gethttp call. Here we're using the back-ticks to create a string with new line characters in it and this is valid JSON. The key thing to remember is that the property names need to be in quotes when you create JSON content. We'll store it all in a variable called jsonIn. Now we'll call parse on the JSON object, passing it our jsonIn and when we block it out we get the actual object now, not the JSON string. Let's take a look at this in Visual Studio code. Here's the code from the slide and I saved it and let's take a look at our objects. You can see them here, carId 123, 456, and 789. So we took our JSON string and called JSON.parse in order to parse it into a regular JavaScript object and to parse it back into a string as we saw earlier in the slides, we can call JSON.stringify, passing it the object carIds, which in this case is an array. I'll save it and you can see here is our JSON content. It's a large string. I'll make the browser wider and you can see it more clearly. That's all we have for objects now and in the next clip we'll take a look at arrays. Array Iteration I covered the basics of arrays in my JavaScript: Getting Started course and most beginner courses will go into arrays. So I'm not going to cover what they are or some of the common properties such as length or the common methods on them, but one thing I do want to cover is iterating through an array. It's okay to use a for loop to go through an array, but there are methods on the array object that we can use to make iteration easier. Let's take a look. Here we have an array and each object in the array has a property carId and style and we're working with a simple array here, but of course it could be thousands and thousands of elements and arrays have a method called forEach and what this method does is it calls a function on each element of the array. And you can see that I'm using an arrow function. The parameter is car and we'll simply log out car. So this line will log out our three car objects and here you can see we're calling forEach again, but this time there are two parameters, car and index and this will log out each car along with its index in the array from 0, 1, to 2. It'll be 0 for the first car, one and then two for the last car. So index is optional, but there may be cases where you need to know the index. Let's look at another method. We can filter an array and create a new array depending upon whatever our filter is. We'll start off with carIds. That's the same object we saw earlier. This time we'll call carIds.filter. This will loop through the entire array and call this function. Each element will be assigned to car one at a time and we're interested in all the convertibles. We'll return car.style is identically equal to convertible. So after a filter executes, convertibles will be a list of all the convertibles. If we log out convertibles we'll get carId 456. Here's another method called every. We'll use the same array, but we'll call carIds.every. This will return true or false, depending upon the condition. In our arrow function we'll have the car parameter and if car.carId is greater than 0, will return true. So this is just validating that the carId does exist on every element. If it does, result will be true; if it doesn't, result will be false, and we'll log out the result. And this applies to the entire array, not for each element of the array. We want to check if every element passes the test. And there's one more method I want to look at. It's the find method. Sometimes we want to locate the first match of something in an array and we want to do it within a function, not with something like index of. So we call find on carIds and we pass it this arrow function. We're going to find the first instance where car.carId is greater than 500 and we'll set that to the local variable car. Let's go to our editor and see these examples. We're going to call forEach on carIds. We'll log out each element and then after that we'll call forEach, but we'll get the car as well as the index of the element and log those out. I'll save it and let's take a look. We get our three cars right here and then we get our three cars along with the array index, zero, one, and two. So forEach is a simpler and more modern way of performing a for loop. We can use arrow functions or traditional functions as a parameter to this method and let's take a look at filtering. We'll execute carIds.filter and we'll take a look at all the convertibles. Car.style is identically equal to convertible. This will create a new array that will store in convertibles. I'll save it and you can see the array right here. It has one element, carId 456, which has the style convertible. And let's looking at testing the entire array. We'll call carIds.every and we want a true or false value based upon everything in the array. Car.carId must be greater than 0 for the result to be true and it needs to be true in every case. I'll save this and we get true. If one of the carIds was null, I'll save it now and we get false. So every tests every element in the entire array, but we only get one true or false value back and finally we'll look at the find method. Here we'll execute carIds.find and with find we only want to find the first element that matches. So if car.carId is greater than 500, find will stop execution right there and return that car. I'll save this and we get carId 789, which is correct. The prior two are less than 500. So the next time you're working with arrays and you need to iterate through them, be aware of these methods. You might not have to use a for or a while loop with your array. You also might want to check out the Mozilla developer network and find out what other methods exist on arrays. But that's all we're going to cover in this course. We'll wrap up this module with a summary. Summary In this module we took a look at constructor functions. We saw how to use the new keyword on a constructor function in order to instantiate a new object. We also saw how the new keyword creates a new this value for the function. This is where we store properties and methods for the new object. Next we looked at prototypes. A prototype is a property of a constructor function and we saw how to add methods to it. That way every instance of the object shares the same function. You just have to make sure to use the this keyword to access the properties of the object. We saw how to expand objects using prototypes. We can expand common objects that exist in JavaScript. We used string as an example. We can access string.prototype and add our methods there. Next we looked at JavaScript Object Notation, JSON. We saw how to convert a normal JavaScript object into JSON to transmit it and we saw how to take a JSON object and convert it into a regular JavaScript object. Finally we looked at array iteration. We saw several methods we can use in place of a for loop: forEach, filter, every, and find. In the next course module we'll be taking a look at classes and classes is a new way to work with objects in JavaScript. It was released in the ECMAScript 2015 version of JavaScript and it offers a syntax that's a little bit more similar to languages such as Java or C++ and we'll also look at a better way to organize our code using ES6 modules. Classes and Modules Introduction Welcome to this course module named Classes and Modules. Classes give us the new syntax in order to create constructor functions. It's more similar to Java and C++ and C# and modules is a way to organize our code. Generally we can break our source code into a set of files and each file will become a module. We'll start of by covering the class basics. How do we create a class? Next we'll look at constructors and properties. We'll see how to add these to a class. We'll look at methods for performing code on a class and we'll look at inheritance. This is a technique where classes inherit from other classes so we don't have to do duplicate code. Next we'll create our first module and a module is a file that can be shared and imported into other modules. And we'll see how to import those modules and work with index.js and organize our code properly. So let's get started and look at how we can create a class. Class Basics We use the class keyword to create classes in JavaScript and this is an optional way to make a class compared to the constructor functions we've seen. Let's see the code. In order to create a class we use the class keyword and the name of the class. By convention the name is uppercase and the class has a body with curly braces. We'll be filling this in throughout this course module, but this is a valid class as it stands. In order to instantiate an object of this class we use the new keyword just like we did with constructor functions. So we call new Car with the opening and closing parentheses and assign that to the variable car. Here's our example in Visual Studio Code and we're going to log out car. I'll save it and you can see that we get our empty object. Now this isn't too useful yet, but in the next clip we'll see how to create a constructor and start adding properties to our class. Constructors and Properties A constructor is a function that gets executed when a new instance of an object gets created. That's where a lot of setup occurs and that's where we start to work with properties on a class. Here's an example constructor for the class car. It looks a lot like a function. We pass it a parameter id and we'll take id and assign it to this.id. So we create properties using the this keyword just like we did with constructor functions. But now we're working with classes and their constructors. We'll instantiate a new car, passing it the idea of 123 and when we log out car.id that's what we get, 123. Let's see this in action. Here's the code from the slide. I'll save it. And you can see that we do get 123. The important thing is that we always need to be working with the this keyword. If we take that out, let's try to access the variable cid and assign id to that. We get a reference error; cid is not defined. So when we're working with constructors we need the this keyword in order to access properties. Now if we wanted to change this property while we're executing code, let's go ahead and set car.id to 456. I'll save this and now we get 456. So this is only used within the class itself. When we access the object we can reference the property directly, car.id. In the next clip we'll take a look at methods. Methods Methods are functions that exist on an object. Let's see how we work with them. Here we have the class car from before. It has the same constructor, but now we have a method and notice that we don't need a function keyword. We can just go right ahead and name the method and add the parameter list. In this case it's empty. We'll return Car Id: this.id. So again we need to be using the this keyword. That holds true for constructors and methods. We instantiate a new car with id 123 and when we call car.identify we get Car Id: 123. Here's our code and I'll execute it. We get Car Id: 123 and of course with methods we could pass in arguments. I'll pass it three exclamation points and we'll take that as a parameter suffix and I'll save this and we get Car Id: 123 and the three exclamation points. So just remember we don't need the function keyword. We can go ahead and just name our method and also we still need to work with this when we access properties. In the next clip we'll take a look at using inheritance. Inheritance We want to try to avoid duplicating code and one way to accomplish that is by using the concept of inheritance. Classes make this easy. Let's take a look. Let's say we have a class called vehicle and our application might have several different types of vehicles. We could have trains, planes, automobiles, but each one of those vehicles will have its own class, but they can be derived from this class, vehicle. This is sometimes called a super class or a base class. In the constructor we're setting this.type equal to car. That's the default. That would be overridden to trains, planes or what other vehicle you have. And we have a simple method called start. We'll return starting and this.type. We're not going to instantiate a vehicle directly. We want to work with a car, but we can have car take all this functionality from vehicle. So here's our car class and you notice that we have a keyword extends. We're going to extend that vehicle class we just saw and we don't need any other code in this class. The only code that would go in this class is code that's unique to car. We'll get all the vehicle's functionality by extending it. So when we instantiate a new car, let's log out car.type and we will get car. We don't see a type here on this class, but we see it on vehicle. I'll go back to the previous slide and the type is right here. It defaults to car. Going back to the car class, so in this case we would say that car is inheriting from vehicle or car is extending vehicle. Let's see this in action. So here's our example from the slide. We'll log out car.type and I'll save this and we get car. So even though there's no type here within the car object itself, we're extending vehicle. So all of the properties in vehicle become accessible. Type is set right here to car and if we didn't extend vehicle, I'll take that part out, I'll save it, and now car.type is undefined. So let's make sure car extends vehicle again and what if we had a constructor for a car? Right now it's empty, but let's save it and see what happens. We actually get an error. Reference error. Must call super constructor in derived class before accessing this or returning from derived constructor. What that means is we need to call the constructor up here first and the way we do that is we call super. It's a special function that refers us back to the constructor in vehicle, the super class. I'll save this and now everything's fine and I'll take out this constructor just to save space, but what if we had a method here called start? Now we have a method both in vehicle and in car. Here I'll return in Car start and we'll log out car.start. I'll save it and you can see that this is the method that executes. The car method, but how can we access the start method in vehicle? Again we do that with super. Let's say in Car start + super.start. And again by using super we can access vehicle, the base class or super class. I'll save this and we get in Car start and the appended string Starting: car. So that's how we work with inheritance using classes in JavaScript. In the next video we'll take a look at modules. That's a way of organizing our code. Creating a Module So we saw how to work with classes and an application might have dozens or even hundreds of classes. How do we organize all this? Well the answer is to use classes within modules and any JavaScript code can be placed in a module. There have been many different types of modules, but in this course I'm focusing on the latest version of modules in the JavaScript ES6 version, also called ECMAScript 2015. And because we're using webpack as we saw in the introduction to this course, modules are very easy to work with. Let's go to Visual Studio Code. So here's an example from before. We have a simple class called car with a constructor and we set up an id property, but we can't just throw all our class definitions into index.js. We want to break out each class into its own file and each one of those files will become a module. Let's do that. So we have our scripts folder and we have our index.js file, but let's add a new folder and we'll call it models. These will hold our data models such as car, vehicle, airplane, anything else we need to add to it. And in models we'll create a new file and we'll call it car.js. So right now it's empty, but let's paste our car class into it. I'll cut it out of here and we'll put it in car.js and in order to make this a useful module, we need to add a new keyword. It's called export. That will export the class car. Now we could export anything. We could export a regular variable or a function, but in this case we're exporting the class car and I'll save this and we just created our first module. So now all the functionality that has to do with cars goes directly in this file. It doesn't need to make index.js more complex. It simplifies things, but if we go back to index.js we can't use car yet. If we save this you'll see that we get an error. Car is not defined. So we need to import car from that file into index.js and we'll see how to do that in the next clip. Importing a Module So we saw how to create a module. We used the export keyword in order to export our class car, but now we need to import that module into our index.js file, which itself could be considered a module. Let's go to the code. So we have our reference error car is not defined and the way to define it is to pull in that module. We used the keyword import. We'll use curly braces and Car, which is the exported identifier. This is our class that we can instantiate and we need to tell JavaScript where to look for it. It's in the base directory /models/car.js and I'll save this and now everything is working fine. We get the value 123. Car is being pulled in from its own module into the index.js module. So when you create your application you may have a very complex set of files. Here we only have car.js in the models folder and index.js, but you may have folders for some algorithms you need, for some utility classes, for some user interface classes, and you could easily have dozens or hundreds of files organized right here, but because we're using webpack and now that we know how to use modules, we can easily organize all this code. Let's wrap up this course module with the summary. Summary We started off this module by looking at the basics of creating a class. We used the class keyword with our ClassName, which is by convention in uppercase and we give it a body with curly braces. We looked at constructors and properties and we saw that we always used the this keyword for properties. We looked at how to create methods and we saw how we could avoid duplicating code by using the concept of inheritance. The syntax for that is class and the class name Car extends. That's another keyword. To extend the vehicle class. And we looked at creating a module. Basically we export anything we need to use in another module. We saw how to export a class, but you could just as well export a variable, a constructor function, a regular function, or anything. And we saw how to use the import keyword in order to import something that's been exported in a different module. So now you know how to organize your code into classes and by putting each class in a file it can become a module. You export that class and import it wherever it's needed. In the next course module we'll take a look at programming the browser. We'll look at the browser object model and the document object model to see how to work with web pages and other features of the browser. Programming the BOM and DOM Introduction Welcome to this module titled Programming the BOM and DOM. My name is Mark Zamoyta. BOM refers to the Browser Object Model and that lets you access functionality in the browser. You can change the URL you're pointing at, get information on the URL, and that kind of thing. And the Document Object Model is the DOM. That's what we use to change the actual web page. These are large topics so we'll cover just the basics in this module. That'll be enough to get you started and you'll be able to work with the Mozilla developer network to find more information. We'll start off by looking at the window object, which is JavaScript's global object that we can access from anywhere. Next we'll look at timers. You use a timer to fire off a function asynchronously after a set amount of time. We'll look at the location object. That lets us access the URL that the browser is pointing at and we'll look at the document object. That's where DOM programming comes in where we can change the elements in a web page. We'll look at a few methods to select DOM objects and we'll also look at a few methods to modify DOM objects. So let's get started and look at the window object. The window Object Window is the global object in JavaScript. We can access window from anywhere and let's take a look at some of the properties, methods, and events on window. For properties, one of the most important properties is document. That's our DOM, the Document Object Model. And we'll go into some detail on that later in this module. Location is a property on window that gives us details on the browser location and we've been working with console all along. When we say console.log to log out something, console is on window, the global object. Also for properties we have innerHeight, innerWidth to get the dimensions of the screen that the browser gives us and pageXOffset and pageYOffset to get information on where the scrollbars are positioned. And there are many other properties that we can look up on Mozilla Developer Network. As far as methods go, again there are lots of methods, but some of the common ones you see are alert to show an alert dialog, back to browse backward in your browser history, and confirm also shows a dialog. That gives the user a yes or no choice. And for events there aren't really any common events on window. There are some that you can find on Mozilla Developer Network, but for the most pat you're interested in events on document, the property. Let's take a look at Mozilla Developer Network. So I went to developer.mozilla.org and I searched for window. We can scroll down and here we have window. You can read about the window global object here or you can access its properties, methods and how to set up event handlers, and it's definitely worth going through all this documentation just to get the full capabilities of what window can do. And again, there are hundreds of properties and methods and events for window. Let's take a look at window in Visual Studio Code. Here we're setting year to 1956, but we're not saying this.year and we're not saying window.year; we're just making up a variable and using it and that gets placed on a window. If we console.log out window.year, we get 1956. So window is the global object, but let's see what happens if we import a module and we make this into a module by means of using an import. I'll save this and we get an error. Year is not defined. So when we're working with modules we need to make sure to declare our variables because they will not be placed on the global window object. So we could use the let keyword to declared year at the module level, but we could still go ahead and access window.innerWidth or some other property on it and we get 400, the width of the browser right here. And if we left off the import statement we could even leave off window because inner width would refer to the global object, the window object. I'll save it and again we get 400. So window is the global object, but when we're working within a module we have to reference it specifically, window.propertyname. In the next clip we'll take a look at timers. Timers Timers are important in JavaScript. They fire asynchronously so events can get handled and other code can execute while you're waiting for a timer to fire. Timers are used for animation, to handle things with the user interface, for video games, and lots of other uses. Let's see how we work with them. SetTimeout is a JavaScript function that's accessible globally. It lets us execute a function at one time in the future. Here we're calling setTimeout and we're passing it a function. The function simply logs out 1 second passed and the second argument to setTimeout is 1000. That's the number of milliseconds to wait before executing the function and notice that we're assigning the return value of setTimeout to a local variable timeoutId. We can use this timeoutId to cancel the timeout if we want to. We call clearTimeout, passing it the id and again this only fires a function off once. If you wanted to fire off a function repeatedly we have setInterval. SetInterval takes some more arguments. A function to call and the delay in milliseconds between calls to this function. SetInterval will fire repeatedly so you need to hold on to the return value. Here we're assigning it to intervalId and to cancel this timer we call clearInterval passing it the intervalId. Let's see this in code. Here we have the slide that calls setInterval. Let's just comment out clearInterval because we don't want to clear it yet. I'll save this and after a second we get 1 second passed and you see this indicator here increasing. That just shows that for every second that passes our function is getting called and it is printing out 1 second passed. So I'll uncomment out the clearInterval. I'll save it and now nothing shows up. As soon as we created the interval we cancelled it. So we call clearInterval passing it the intervalId in order to cancel out the timer and we're using setInterval here, but if you wanted to call the function only once, you would call setTimeout instead. And you could clear that out early by calling clearTimeout, passing it the id. In the next clip we'll take a look at the location object. The location Object The location object is part of the BOM, the Browser Object Model. We get information on the URL that the browser is pointing to. Here are some of the common properties and methods on location. For properties we have href which is the URL we're pointing to, but location also breaks that down into the host name, the port, the path name which comes after the host name in the URL, and search information. Any query string we have in the URL. For methods we have assign to assign a new location to the browser or reload, to reload the current URL and there are no events on location that are used commonly. To get all the information on location, you can pull up the location page on developer.mozilla.org and check out the Properties and Methods. Let's go ahead and we'll log out location.href. That's the URL we're pointing to and here we see localhost 1337 and that's what we have in our address bar. So we can get access to that in JavaScript. An interesting thing about location is that right here we're accessing it on window, the global object, but we can also access it from document. I'll save it and you can see we get the same result. In the next clip we'll take a look at document. That's the Document Object Model, the DOM. The document Object Next we'll take a look at the document object which is used to program the DOM. The Document Object Model. The DOM is a huge topic so we're only going to cover it briefly here and here we have some of the common properties, methods, and on document. There are hundreds of these so you'll want to check out the Mozilla Developer Network, but some of the properties are body which refers to the entire body of the HTML page; forms to get a list of all the forms on a web page, and links to get a list of all the links on a web page. As far as methods go, createElement can be used to create a new HTML element and createEvent creates a new event to fire on the DOM. GetElementById singles out a specific element to retrieve from the DOM and getElementsByClassName will return all of the DOM elements for a passed-in class name. And for events we have onload, which fires after the document loads; onclick for a mouse click or a finger tap, and onkeypress when a key is pressed. And again there are hundreds of these properties, methods, and events so check out the Mozilla Developer Network to get a list of everything. In the next two clips we'll be looking at document in more detail, specifically how to select nodes and also how to modify nodes in an HTML document. Selecting DOM Elements Let's take a look at how we can select DOM elements out of our HTML page. Here are some of the common methods that we have on document to find an element. We can call document.getElementById, passing it the id of the element. And if we wanted to get an array of elements we call document.getElementsByClassName, passing it the name of the class we want to retrieve. And again this returns an array because multiple elements can have the same class name, unlike the id, which is supposed to be unique and document.getElementsByTagName will let us retrieve all the elements of a specific tag name. We could grab all the paragraph tags or all the h1 tags and there are actually many more methods to select DOM elements, but these are some of the most common. I added a few paragraph nodes to the DOM so that we can work with these in this clip. The first paragraph has a id of first and a class of p1 and the text First Paragraph. The second paragraph has a name, name1 and a class p1, and the third paragraph has a class of p3. So I'll make sure this is saved. So the first thing I want to select is the element with id of first, this paragraph right here. I'll say let el, el for element, = document.getElementById and I'll pass it the name first and let's log that out. I'll save it and we get our first paragraph right here. And now that we have that saved in the local variable el, e-l, there are all kinds of properties and methods we could access on that and we'll see that in the next clip, but for now let's look at a few different ways to select elements. Let's get all the elements which have a class of p1, specifically these two paragraphs right here. We'll call document.getElementsByClassName and we'll look for the class named p1 and I'll call it els because we're working with an array now. I'll save it and we get what's called an HTML collection, which acts as an array. We get our two paragraphs. If we wanted to see just the first paragraph we can subscript it. We'll say els subscript 0 and we get our first paragraph. Subscript 1 will be the second paragraph, and we see that here. And finally we can call getElementsByTagName and let's just search for the p elements, and we get an HTML collection of three elements. I'll open it up and here they are. There are a few other ways to access elements and search for them in the DOM. You can take a look at Mozilla Developer Network to find out more information. In the next clip we'll take a look at modifying one of these elements. Modifying DOM Elements We often want to modify DOM elements. We can change their properties, set up event handlers, and modify the visual aspect of the web page any way we'd like. In order to modify a DOM element we need to select the element first. Here we're calling getElementById, just getting a single element. Once we have it we can access a few properties or call some methods on it. To modify the text content of a paragraph or a div or some other element with text content we access element.textContent, setting it to the new string. If we wanted to add an attribute to an element, we call the method element.setAttribute, passing it the name of the attribute and the value for that attribute name. To add a new class to the element we call element.classList and classList is a property an element, but we access its add method. We pass it the name of the class that we want to add to the element and to access CSS information and to change that on an element, we access the style property. Here we're setting element.style.color to blue. Here we're calling document.getElementById and we want that first paragraph. We'll store that in the variable element. To change the content of the first paragraph we specify element.textContent and we'll assign a new string. I'll save it and new content shows up on our web page. If we wanted to add a new attribute to element, we could call element.setAttribute and I'll just make up a dummy one for now. We'll call it foo and we'll call it fooValue. That'll be the attribute's value. Let's also log out element. And here we see our attribute. Foo is set to fooValue and you'll notice that this element has a class of p1, but let's add a class of p2. We'll access element.classList and from that we'll call the add method. Let's add the class p2. I'll save it and now for class we have p1 and p2. A very common thing to do is to work with CSS properties. We can access element.style and then we can specify a property, in this case color. Let's set it to blue. I'll save it and now our first paragraph is showing up as blue. DOM programming is a very detailed subject. There are hundreds of properties, objects, and methods and events that you could use. See the Mozilla Developer Network for more information. Summary In this module we looked at the window object. We saw some properties and methods on it and we saw how this was the global object that we can access anywhere in JavaScript. We looked at timers, specifically the setTimeout function where we can execute a function once after a set number of milliseconds. And setInterval where we can execute a function over and over until we cancel it. We saw the location object, which let us access the URL in the browser and we looked at the document object for DOM programming, changing the actual web page itself via JavaScript. We saw how we could select DOM objects and we saw a few methods that would let us modify DOM objects. So that covers the browser object model and the document object model for this course. In the next course module we'll take a look at error handling. Promises and Error Handling Introduction Hi. My name is Mark Zamoyta and this module is titled Promises and Error Handling. When something goes wrong in a JavaScript program we want to be in control. So we'll look at the mechanisms in place to help us handle errors and make sure everything runs smoothly. We'll start off by looking at general errors in JavaScript and how they stop execution of our code. Then we'll start handling errors with the try and catch keywords. We can specify code blocks with try and if any errors occur we can catch them with catch. We can also add a finally code block to try and catch. So we'll take a look at that. While JavaScript creates its own errors, as a developer we can create errors unique to our application. So we'll see how to do that and throw those as errors that can be caught. Next we'll take a look at promises. Promises are used with asynchronous code and you can think of a promise as a holder for a value. When an asynchronous operation finishes the promise will be notified if there is an error or if everything went smoothly and we have a value to work with. And finally we'll see how we can settle a promise. A promise can be resolved or rejected and a rejection of course is an error handler. Something's wrong and we need to handle things gracefully in our code. So let's start off and we'll look at errors in general in JavaScript. Errors in JavaScript When we run into an error in JavaScript we want our code to handle it gracefully. Let's see an example where we're not doing any error handling at all. We're declaring a new variable car and we're setting it to newCar. The problem is that newCar doesn't exist. We're going to get a reference error. So when this error gets raised what happens to our program execution? Will our console.log actually log out our string? So here's the code from the slide in Visual Studio Code and let's execute it. So we have our error. We know we were going to get a reference error, but if you load the error we can see that execution stopped and we didn't log out the word continuing. So as soon as an error is thrown our JavaScript code stops executing and that's not usually what we want, especially in an application. We want to be able to handle errors gracefully and have our code continue running. In the next clip we'll look at a mechanism that allows us to do that. Error Handling Using try and catch One way to handle errors is with the try and catch keywords. Let's see how we use these. So here's our code that we know has an error, but notice that it's wrapped up in a block now with the curly braces and this is called a try block. We're going to try to execute the code here, but if there's an error we're going to catch that error in this catch block and our catch block will only execute if an error is thrown in our try block and at the end of this code we'll just print out the word continuing … , just to make sure that our program is still executing. Here's the code from the slide and let's execute it. So now we're not getting an error; it's not in red. We're printing out error: and then our error object shows right here. It's a reference error, newCar is not defined. So we are catching our error and if we look at the bottom of the log, we do see continuing. So our catch block catches the error and execution of our JavaScript continues as usual and that's what we want. So looking at the code again, the try blocks executes and if any error is thrown our catch block will execute, and after this executes, the program will continue as usual. In the next clip we'll take a look at the finally block, which can be added to try and catch. finally Sometimes when we're working with try and catch we're going to want to execute some code regardless of whether or not an error was thrown. So a finally block always executes. And here we can see one right here. Our try block may or may not throw an error and catch may or may not catch it, but finally is guaranteed to run. A finally block always executes. Let's see this in Visual Studio Code. Here's the code from the slide and I'll save it to execute it and we're logging out our error. So there is an error being thrown and our catch block is catching it and this always executes shows up in the log. So let's say there is no error in the try block. I'll set car = null. I'll save it and no error was thrown, but our finally block did execute. This always executes is showing up. So far in this module we've been looking at errors that JavaScript throws, but as developers we can also throw our own errors and we'll see how to do that in the next clip. Developer Defined Errors We've seen JavaScript throwing errors, but as a developer we can throw our own errors. An error can be a simple string or it can be a more complex object. Let's see how we work with these. So here we have our try, catch, and finally blocks and normally your try block will have a lot of code in it, but at some point in that code, you might want to raise your own error so we'll use the throw keyword to throw an error. We're creating a new error object. Error is built into JavaScript and the data for that error will just be a simple string, my custom error, and since we're throwing this error, it will be caught in our catch block and our error object will be assigned to this error parameter right here. Let's see this code in action. So I'll save this. We're logging out our error that we're throwing right here. It has the value my custom error, just like the error that we created in our try block and of course, if we look at the bottom of the log, finally should have executed. And we see it right here. One thing you could do instead of throwing just a string within an error object is you can create your own error object. Something that inherits from error. And that way your error object can have its own properties, but that's beyond the scope of this course. In many cases it's fine just to throw a string the way we're doing here. So that covers try, catch, finally blocks. In the next clip we'll take a look at a totally different way of dealing with errors. We'll look at promises. Creating a Promise There's another way we can work with error handling and that's by using promises. Promises are designed to work with asynchronous JavaScript. So if you're working with a timer or if you're working with HTTP calls, you can think of a promise as a temporary holder for a value that you'll retrieve once an asynchronous operation completes. So I like to think of a promise as a promise to actually get a value back to you. It might take some time because we're waiting on an asynchronous call, but eventually you will get a value back or at least an error. And here's an example of creating a promise. Promises built into JavaScript since the ECMAScript 2015 version and before that you would have to use some third-party library such as Q. If you want to look that up it's just the letter Q, but here you can see we're creating a new promise and we're passing it one argument. It's a function that will accept two more functions as parameters, resolve and reject. So this function will execute immediately once we create this promise. So setTimeout, that sets up a timer where the resolve function will be called after 100 milliseconds and we'll just pass resolve one argument called someValue as a string. So by calling resolve that means that the promise resolved successfully. If there was some kind of error we would use reject instead of resolve. Let's see this in Visual Studio Code. Here's the code from the slide and I'll log out the promise that we're creating. Here we see the promise and the promise is pending. That's because at the time we logged out promise, our 100 milliseconds had not elapsed yet. If open up this promise object, we can see that the promise status is resolved. So that's one thing to be aware of. In our log it's not going to update the promise status. It still shows as pending, but when we look inside it is resolved and what happens if we called reject instead of resolve? I'll save it. We get our promise and we can see that the promise status is rejected. Also you can see that we have an uncaught exception that was thrown. So in this code we're only creating a promise. We're not really working with it to get some value right here that'll get returned by the promise. In the next clip we'll see how to do this. Settling a Promise As I mentioned earlier, a promise represents a value that we don't have access to just yet. When we do get the value of a promise, it's referred to as settling a promise. Let's see the code for this. We're creating a new promise right here and we'll resolve it after 100 milliseconds. Notice that we're saving our new promise in a local variable called promise, lowercase. In order to get the value from our promise we execute promise.then. This is a function and it takes two arguments. They're both functions. The first function will execute when the promise is fulfilled. That means it resolved successfully and the second argument is a function that executes if there's some kind of error, if the promise gets rejected. Because of the asynchronous nature of promises, you might have to wait some time, whether for a timer, an HTTP call, or some other asynchronous event and you'll have to wait for that until one of these two functions get executed, but that's what promises are all about. They're about handling a success value or an error value from asynchronous operation. So here's the code from the slide. Notice that we're resolving the promise. I'll save it and you can see that we get fulfilled someValue. So the promise was resolved. The first function executed. What happens if we reject the promise? You can see it logs out rejected someValue so our promise has an error condition. It's rejected. Many times you won't need to create a promise. Many third-party libraries do this for us, but almost always when we're working with promises we need to execute the then function on that promise, passing it the fulfilled and rejected functions. Promises have many other advanced features and you can find out about those on the Mozilla Developer Network, but by calling the then function on a promise you can handle any success or error condition. Let's wrap up this module with a summary. Summary In this module we took a look at errors in JavaScript. It's always important to know when JavaScript is going to stop execution. We want to handle errors gracefully. We took a look at using try and catch blocks to handle errors. We saw how the catch block would execute on an exception in the try block. We saw how finally is a code block that always executes. It comes after a try and usually a catch and whether an exception is thrown or not, the finally block executes. We looked at developer defined errors. We saw how we could use the throw keyword to throw an error and we could throw a string or we could throw an instance of JavaScript's error class or we could even make our own user-defined objects that could be thrown as errors. Those would be used in a more complex application. Then we looked at creating promises. When creating a promise the key thing we need is a function that gets passed a resolve and a reject function. If our asynchronous call is successful we usually call resolve, passing it the data from the asynchronous event. If there was some kind of an error we would call reject. And we looked at settling a promise. Once we create our promise, we call the then method on it and we create a fulfilled function and a rejected function. The fulfilled function would be in the case of a success and the rejected function would be in the case of an error. So that's all we have for error handling in this course. In the next module we'll take a look at using HTTP and of course we'll be using promises there because HTTP calls are asynchronous and we'll look at different ways of communicating over the web. Data Access Using HTTP Introduction Hi. My name is Mark Zamoyta and this module is titled Data Access Using HTTP. We'll start of by looking at the HTTP protocol to request data using the XHR mechanism. XHR is very low level as we'll see and it's much more common to work with a third-party library such a jQuery for data access. So that's what we'll do next. We'll do an HTTP request using jQuery. We'll see how to load jQuery into project.json and how to import it as a module so we can use it in JavaScript. And finally we'll do an HTTP POST using jQuery. This is how we can post form data or post other information to an endpoint that's accepting data. So let's start off by looking at what XHR is. HTTP Requests Using XHR The first form of communication we'll look at is HTTP requests using XHR, and if we look at this acronym XHR, the H and the R stand for HTTP requests, but the X actually stands for XML and that was the popular file format when this was created. A lot of data transfer was done using XML, but things have gradually moved over to JSON. They're both text file formats and they both work equally well, but XHR is built into browsers and it's been in browsers a long time. Let's see how this works. To work with XHR we create a new instance of an XML HTTP request object and we set up an event handler. We want to handle the on readyState change event and if we look at this event handler, we see one of the key problems with using XHR directly. We need to be aware of the underlying protocol status result codes. We need to know readyState values and we need to know status values and because of this, XHR is rarely used directly. It's much easier to work with a library such as jQuery and deal with communication within promises, but if the ready state is for and if the status is 200, that means we got a successful response with data so we'll lot out this.response text. Now to actually make the call over HTTP we call xhttp.open. We use the GET method and pass the URL. And you can see here that I'm using mockapi.io. Let's just quickly go there. Mockapi.io is a web service that lets you work with HTTP calls with made-up data. I'll just sign in with my GitHub account and here's a problem we're using for this course and you can see that I have this users endpoint and this is the URL I would use, but if you wanted to work with a mock API, this is a great site to use. So once we have our URL all set up, we call xhttp.send. That'll send off the HTTP request and hopefully we get our return code as being successful. Here's the code from our slide and the only change I made was I put in the unique id number from mock API and I'm getting the user's data right here. So I'll save this and you can see that we did get a successful response because we have this large array now. We have user id 1 and all of its related data, user id 2 and all of its related data, and so on. And again it's not very common to work directly with this XHR technology. If we wanted to handle an error we would need to fully understand all the ready states and all the HTTP status codes. So in the next two videos we're going to stop using XHR and we're going to start using something much more common, jQuery. That way we can work with promises and things will be much simpler. HTTP Requests Using jQuery Let's look at HTTP requests using jQuery. The first thing we need to do is install jQuery into our package.json file. We do that from the command line calling npm install jquery. That will pull down the latest version of it and then once we have jQuery loaded into node modules we need to import it into our JavaScript. So we have the import statement and it's traditional to use the $ sign for jQuery and we don't need the curly braces around the $, which is just a simple variable name, because jQuery has its own default export. So when we use jQuery we can go ahead and just use $. And the method on $ is get to do a simple HTTP get. We pass it the URL and we pass it a success handler. We'll simply log out the data right here and while this works, it's not the best way to use the get method. This method returns a promise so we can go ahead and use that. So when we call $.get we'll save it to the local variable promise. We'll set up our handlers with promise.then and this function will get called on a success and this function will get called on an error. Let's see this in Visual Studio Code. I already installed the npm package with npm install jquery. We can just verify that it's there. I'll go to package.json and in dependencies we see jQuery right here and I also updated the id so that we can use the mock service that I'm using. So I'll save this in order to execute it and we get success along with our 10 users. Now just to make sure that the error handler works, I'll just add a z at the beginning of the URL. I'll save it and we get our 500 internal server error. And you see the error: here? That shows that the error handling from our promise is working. So using jQuery like this is the easiest way to be working with HTTP. In the next video we'll take a look at posting data which is what we would do when we're posting a form or posting some other information. HTTP POST Using jQuery Let's take a look at how we can use jQuery to post over HTTP. This would be used for posting a form or posting other information. We'll import jQuery as the $ and we need some information to post so we have an object literal and our user just has a name an avatar file. We're not posting the file, just the file name. And then we call jQuery as the $.post. We pass the URL and our data and we want to use this as a promise. We call promise.then, passing it our two handlers. The first one for a success and the second one for an error. Let's look at this in code. So here's the code from the slide. I'll save it and the promise resolves successfully. We log out data: and the data right here and that's what we get. You see the name and the avatar were set, but we're also getting back an id, id 11 and the date and time it was created at and that's important to know. When the server assigns a unique id we get that information back. And let's force an error here. I'll just add a z at the beginning of URL to invalidate it and I'll save it and now we have an error. So our promise is working fine. Again on a post we can't see it here. Let me widen the window, but on a post you need to make sure to send the data that you want to post as we see right here in the user variable. So that's all we have for data access with HTTP. For more information see the jQuery documentation on working with HTTP. Summary We started off by looking at XHR, an XML HTTP Request, but we saw that this was too low level for typical use. Normally we use a third party library that makes things much simpler. So we looked at HTTP requests using jQuery. We saw how to install jQuery and use it as a module. We assign jQuery to the $ variable so we can call $.get, passing it the URL and that returns an object that we can use as a promise. Next we looked at an HTTP post using jQuery. We call $post, passing it the URL and the data that we want to post. Our data started off as an object literal, but it was passed as JSON and again this also returned an object that could be used as a promise. Get and POST are two of the most popular methods that we use with HTTP, but there are other methods for updating and deleting and you can see the jQuery documentation to see how to work with those. So now that we know how to post data and we also know how to work with promises, in the next module of this course we'll take a look at forms. Forms provide the user interface before data gets posted and we'll see how to work with forms in JavaScript as well as looking at the events we'll need to know and handling forms. So I'll see you in the next module. Forms Introduction Hi. My name is Mark Zamoyta and welcome to this module titled Forms. Forms are the key way we accept data from a user and we want to be able to access these forms in JavaScript so we'll cover that in this module. We'll start off by looking at how we can prevent the default form submission. We want to be able to look at the form data with JavaScript code before it gets posted to a server. Next we'll see how we can access form fields and we use the DOM for that and we'll see how we can show validation errors. Finally we'll look at an alternate way of posting our form data from JavaScript. This way we can bypass the browser's posting mechanism altogether and send data however we'd like to send it. So let's start off by looking at how we can prevent the default form submission. Preventing Form Submission After a user fills out a form, we occasionally want to look at that form data in JavaScript. Let's see how we can do this. So we start off with a form that the user fills out and we have our server where the form needs to get posted. Normally there's a submit button. The button has its type set to submit and when the user presses it, the form gets posted directly to the server. So what we want to do is have our form intercept that submit event. Control will go to our code in JavaScript rather than being posted directly to the server and in our JavaScript code we can do some validation. Make sure all the form data is okay before we send and we can also format the form data. Maybe the server is expecting the data in a different format than what the form will give it. So once everything's okay in Java we can go ahead and post that data to the server. So let's take a look at how we can intercept that submit event. The first thing we do is we get access to the form. We call document.getElementById and the id is user-form and then we add an event listener. We want to listen on the form for the submit event. When that happens either by clicking on the button or having the user hit Enter this function will execute and we'll be filling out this function throughout this course module, but for now we want to execute event.preventDefault and that's what prevents the data from being sent directly to the server. Let's see this in action. First of all, let's take a look at the form we're going to be working with. It's right here. It has the form beginning and ending tags and we're going to post it to a dummy URL right now. We'll send it to the path somepath and we'll do a post method=post, and of course we need the id in order to get access to this form in JavaScript. The first input field is simply a user name field and we can take a look at it here. I'm not adding labels. I'm just adding the placeholder text and the second field is avatar-file. And that's just the ping or jpeg file that has an avatar image. You'll also notice these spans. We're going to be working with these soon. These have to do with placement of any error message that might come up, but we can ignore those for right now and finally we have our submit button, a button of type submit. Looking at our JavaScript we grab our form right here and we call addEventListener on it and we want to listen for the submit event and when that happens we'll call event.preventDefault. I'll save this and you can see that nothing happened. The URL didn't change for the posting. If we take out our preventDefault call, I'll save it and I'll fill out the form with some dummy data and I'll hit the submit button. And you can see that the post was attempted. We're not interested in handling the posting in this course. We're mainly interested on the JavaScript side on the client, but you can see in the browser it did try to go to our path. So depending upon the logic that we'll be adding to this function, we may or may not want to call event.preventDefault. In the next clip we'll take a look at how we could access the fields in the form. Accessing Form Fields We want to be able to access all the data a user entered into the form and HTML and JavaScript make this easy. Here we have our event handler that we set up in the last clip. We're listening for the submit event and these two lines right here give us access to the forms fields. On our form object there's a property called elements and we can get access to each form control by using the forms name. So the name is user in this case and the name is avatar-file for our second input. And once we have these controls, we access the value property. So we log out user.value and avatarFile.value. And we're still not ready to post to the server so we'll leave in event.preventDefault. So here's our code from the slide. I'll save it and I'll just add some dummy values into the form. So for username we'll put some As and for avatar-file we'll put some Bs. I'll hit the submit button and we get user.value right here and we get avatarFile.value right here. So this is how we get access to the fields in the form. We can go ahead and disable these fields, change their values, or perform any method or work with any other properties. And one thing we might want to do is do some kind of validation on these values. We'll see how to do that in the next clip. Showing Validation Errors We want to be able to validate our form data and then show validation errors. Here's the first form field we've been working with. It's an input with the name of user, but it also has a span attached to it. This span is empty, but this is where we can put our validation error. We just have to access it by grabbing the id user-error. And you can see here we're grabbing our user control and we're getting the span, the userError span right here. And once we have these we can style these and edit them as we've seen earlier in the course. We're setting the userERror.textContent and we're accessing some CSS properties. UserError.style.color is being set to red and our user control itself is being styled with a border color of red. The official CSS property name is border-color, all lowercase, but because we're working in JavaScript we need to use camelCase. A dash isn't a valid character for a property name so borderColor is all lowercase with a capital C and then after a field is shown as having an error, we want to put focus on it. So we call user.focus to give focus to that field. Here's our code from the slide. I'll hit the submit button and our span is now populated with invalid entry in red. Also Chrome puts a blue highlight around it, but there is a red border on username. If I tab you can see it better. So this is how we would handle errors. Most likely we would have some kind of conditional, if user.value and then we would do our validation here and all this logic would get wrapped up in the conditional. So if I save this and I'll just enter three characters for name, I'll submit it, we get our invalid entry, but if I have four characters and submit it, we attempt to post to the server. So these are the fundamentals of how we validate form data. In the next clip we'll take a look at posting to the server without using the form itself. Posting from JavaScript In some cases we want to bypass the mechanism where the form posts to the server. That would post named value pairs, but sometimes we just want to post an object literal that we compose in JavaScript that will get transformed into JSON and sent across the wire. Let's see how we do that. Here's our code and I'm importing dollar from jQuery because we're going to use jQuery to perform the post and once we have our fields, our user and avatar file right here, we need to build up the object literal. We can manipulate this form data however we'd like. Here I'm simply grabbing the values for user and for avatarFile. Once we have those values we can post it. Here's our posting data that we're posting to the URL and I'm sending it to mockapi.io. We take our promise and we set up our success handler and our error handler. So I'll execute this. I'll enter some dummy data and submit it and we get success. We have a new id and a created at timestamp. And of course as we saw earlier in the course, if something were to go wrong, our error handler would get called and because we're bypassing the form's posting, we have to make sure to call event.preventDefault and this is true in all cases because we're handling the post ourselves. Let's wrap up this module with a summary. Summary In this module we looked at how we could prevent the default form submission. We saw how to handle the submit event on the form and to stop the default behavior we call event.preventDefault. Next we looked at accessing form fields. When we get the form from the DOM it has a property called elements and we use the name of each element as a lookup and that way we can get each field. We looked at showing validation errors. Mainly this is an issue with CSS styling and we can style it with CSS properties or classes. We also saw how you normally want to give focus to any field that has an error. So we take our element and we call the focus method on it. Finally we saw how to post from JavaScript. We posted form data using jQuery and this allowed us to put the data in whatever format we'd like. We just need to make sure to call event.preventDefault if we're going to be doing the posting ourselves. So that's all we have on forms. In the next course module we'll take a look at security and also building our application for production for real use. Security and Building for Production Introduction Welcome to this module titled Security and Building for Production. My name is Mark Zamoyta. At some point our application is going to be finished and we're going to need to make sure that our application is as secure as possible. So we'll take a look at some of the technology we can use to do that and we'll also look at how we can use webpack to make a build for production. We need to bundle a JavaScript file and an HTML file that we can send off to our server that our end users will use. So far we've only been in development mode. We'll start off by looking at the Chrome Developer Tools built into the Chrome browser and we'll see how secure our JavaScript code and global variables really are. We'll see that end users can see all our code and variables. Next we'll look at security and JavaScript's eval function. Eval lets us dynamically execute JavaScript code based on a string and by using it your code could be open to injection attacks. We'll take a look at preventing man-in-the-middle attacks and we'll take a look at cross-site scripting attacks. Finally we'll take a look at how we can build our application for production. We want to make sure that we have a JavaScript file and an HTML file that we can upload to our server for our end users to use. So let's start off by looking at the Chrome Developer Tools. Chrome Developer Tools and Security Our JavaScript source code and all the data it works with isn't secure at all. We can use the Chrome Developer Tools to see why. So here we have a JavaScript file and I'll just add some simple code. So we have a Hello World application and I'll save this so it executes and let's take a closer look at the browser. I'll open it up wider. Hello World printed, but let's take a look at the network tab. We have this file coming across the line called bundle.somehash.js. And this is what webpack builds for us. This is actually an in-memory file. You can't see it on your hard drive and the webpack dev server keeps this in memory and that's what makes it so fast when we refresh the page, but let's select this bundle and look at it more closely. We can see the source code here and it has a lot of functions for webpack, module loader, maybe some polyfills and other code, but if we scroll all the way to the bottom we can see our code right here. Console.log Hello World. So if this was a normal JavaScript file that was not bundled we could look at it very easily, but even when it is bundled with webpack we can still look at the source code and for any source code to run on the browser it's going to be visible by your end users and by hackers and anyone who can pull it off the web. Later in this course module we'll create a production build and that'll minify our code, but it's still accessible by everyone. So going back to Visual Studio Code let's change this to create a global variable. We'll just call it foo, window.foo = we'll say some secret code. And I'll save this. So we're creating a global variable and if we look in the browser I'll click on the Sources tab and we have our bundle here and of course we know we're getting the code, but if we look at the Watch section, I set up a watch for foo and we get our secret code. So any data that's stored as a global variable is extremely easy to look at and that's one reason not to use global variables. But even data that exists within functions or modules could be looked at too. Breakpoints can be set if you're familiar with debugging techniques and any piece of information stored in the program can be looked up. So some things to keep in mind when you're thinking about security for your JavaScript programs. Don't store passwords, secrets, or other sensitive information. If you need to hide it from hackers or end users it shouldn't be stored on the browser at all, even if it's stored in a closure or what you think might be a secure module. People can still access that information on the client side. And as we saw, we don't want to use global variables. Those are very easy to look at and manipulate. Assume hackers can read your JavaScript code and access all the data sent to a browser. There just isn't any real security on your applications if you want them to run inside a browser. If you do want to make things a little bit more difficult for people to read your code and look at your data, you can use what's called a JavaScript obfuscator. I'm on a website called javascriptobfuscator.com and let's take a look at what this does to our source code. I'll click on the Online Obfuscator. On the left side we have some JavaScript code and you can paste in your own code if you'd like and I'll hit the Obfuscate button. And here we see the code that was generated. It's very hard to read and translate it back into the original source code. So an obfuscator makes your code a little bit safer, but there are tools that will decipher this and make it into more meaningful code. So the rule of thumb is don't store any sensitive information in JavaScript variables on the client side at all. Don't use global variables and assume that all your code and data on the client side is being looked at. In the next clip we'll take a look at JavaScript's eval function. We'll see how using this function can cause some big problems. Security and the eval() Function Next we'll take a look at security and the eval function. JavaScript's eval function accepts a string and it will parse that string and execute the code. So here we have an input string and while this is a string it is code that could execute. We'll call console.log passing it Hello. And then we use JavaScript's global eval function, passing it that input string. I'll save this and you can see that console.log executes. We get our Hello string to show and this is very powerful for dynamic programming and letting users create their own source code that can run within your app, but it's also extremely insecure. For example let's say inputString came from some database or a web service and that database or web service was compromised. This could be altered to execute any code. Let's show an alert. And we get our alert box. So a hacker or someone up to no good would be able to execute any code on your users' browsers and many people say avoid eval altogether. You're better off just adding script tags to your HTML page and loading all your JavaScript code that way. So by avoiding eval it'll help you avoid injection attacks. In the next clip we'll take a look at man-in-the-middle attacks and how we can deal with that. Preventing Man-in-the-middle Attacks Let's see what a man-in-the-middle attack is and how we can prevent it. Let's say we have a server that's going to serve up an HTML file to client. By the nature of the web there could be many, many servers in between the original server and the client and most of the time these servers will pass through the HTML file just fine, but it is possible that somewhere along the line a hacker, which would be the man-in-the-middle, could insert a script tag into your HTML file and could execute any JavaScript that he or she would like. This is called a man-in-the-middle attack because somewhere between the server and the client there's a pass-through server that is insecure and a hacker has access to it. So how do we prevent these man-in-the-middle attacks? Unfortunately, there's nothing we can do directly in JavaScript. We have to handle things at the server side and in the HTTP side. First of all, by using SSL all communications are encrypted, making man-in-the-middle attacks much less likely. And there are ways to guarantee that SSL will be used by using an HTTP header, Strict-Transport Security. It's beyond the scope of the course to get into all the settings for this header, but you can search for it on the web to get more information. And we also want to make sure that cookies are secure. If we're using SSL we want our cookies to guarantee that they're only transferred over SSL as well and there are attributes for that on cookies, Secure and HttpOnly. And again we're not going to cover that in this course, but I just want you to be aware of the mechanisms used to prevent this kind of attack, a man-in-the-middle attack. In the next clip we'll take a look at cross-site scripting attacks and what we can do about those. Cross-site Scripting (XSS) Let's take look at what cross-site scripting attacks are. This is abbreviated sometimes as XSS. In a cross-site scripting attack we have a server that's going to serve up files to a browser on some client. Let's say it sends an HTML file and of course that HTML file will most likely have some JavaScript tags in it. The script tags can reach out to other third-party servers. So perhaps a JavaScript file needs to be retrieved from a third party and sent back to the client and that's what we refer to as cross-site scripting. We want our scripts to come not just from the original server, but from third-party servers as well and that's extremely common with things like Google APIs and many, many other third-party servers. The problem arises when one of these third-party servers gets compromised. A hacker shows up, gains access to the server and can return any JavaScript file it wants and unfortunately there's no way to prevent this directly in JavaScript. There's no syntax for it and there are no features to prevent it. All of the solutions are on the transport side. So if you want to address cross-site scripting attacks there's a technology called CSP for Content Security Policy. It uses an HTTP header called Content Security Policy and there are many settings for this to make sure that you're retrieving content from the right places and there's another technology called CORS, Cross Origin Resource Sharing. This uses an HTTP header called Access-Control-Allow-Origin and again, these are not JavaScript features. These are HTTP headers and they require setup on the server side and with your HTML files. So I won't be going into more detail on these, but definitely look them up if you're interested in how they work. In the next clip we'll take a look at how we can build applications for production. So far we've only been working in a development mode, but for a production environment there are certain things that need to be done to our source code. Building Your Application for Production So far in this course we've been using the webpack web server, which is meant for development, but when our application is complete, we need to build it for a production environment so we're going to need a package file that we can send off to store on the server. We'll see how that compares to what we're doing now. Here we have a simple Hello World application and I am running the dev server for webpack. I'll save this and it works, but I want to take a look at the files that were generated. I'll go to the network tab and here's our bundle. Webpack bundles up all our JavaScript and stores it in this single bundle file, but if we look at this file it's meant for development. It uses the full variable names. Here we have a parameter modules. It has lots of whitespace in it, all the new line characters, these comments here, tabs, but we don't need all this in a production environment. We need to minimize this code and that's what webpack can do for us very easily. So let's pull up the integrated terminal that we saw in the introduction to this course. On a Mac I can hit Ctrl+Backtick or you could always go to the View menu and select Integrated Terminal. And I'll hit Ctrl+C to stop our dev environment. So I'll cursor up and you can see that the command we used to kick off the webpack dev server was npm run dev, but for a production build the command is npm run build. And notice that we get our cursor back. When we make a build for production we're not interested in having webpacks and memory web server running. What we're more interested in is having a file that we can upload to the server. So now you'll notice that we have this dist folder. This stands for distribution and these are the files that we can distribute to our web server. We have an index.html file. We have our bundle JavaScript file and we have a map file. A map file is useful in some tools for getting the exact line numbers. It maps the minimize code over to the original code so you find out about line numbers where errors occur, that kind of thing. But for now let's just look at this JavaScript file and we can see that it's only two lines of code. The first line is our entire bundle. All the new line characters have been taken out. If we scroll through it we can see that all the local variables such as o here have been minimized. Also if we look at the parameter to this function here it's also been minimized down to the single value e. So webpack took care of this for us. We have a minimize bundle that can be used in production. If we scroll to the end, here's our code for our application where we log out Hello World. So it's that simple to get a production build and to see what webpack is doing we'll go to package.json and we can see the lines that executed on the command line right here. This was for dev and this is for build. I'm not going to get into webpack configuration in this course. You can look that up in the webpack documentation, but you can see webpack-prod.config.js is being used here for build and webpack-dev.config.js is being used for development. And those are the key differences between building a dev build and a production build. If we wanted to look at our HTML file in the dist folder, you can see the script tag that was added. It's a JavaScript file and it includes the bundle that webpack just created. So to move this to production, here's your production build. The JavaScript file, the map if you need it, and the HTML file. Let's wrap up this course module with a summary. Summary and Course Wrap-up We looked at the Chrome Developer Tools and saw the general lack of security that we had for our JavaScript files that are sent to the end user as well as global variables. Other data could be looked at too in the browser through breakpoints and other techniques. All of our code and data is exposed to the end user, which could be a hacker. We saw how we needed to avoid JavaScript's eval function and we saw what a man-in-the-middle attack was and how it could be prevented using HTTP and its headers. We saw the need to use SSL, the Secure Socket Layer and related mechanisms in order to prevent man-in-the-middle attacks. We looked at cross-site scripting attacks, how they occur and we looked at some of the technologies that could be used to prevent them. And we wrapped up this module by building for production. Instead of using the development webpack server we created a JavaScript and an HTML file. Instead of executing npm run dev for development, for production we used the command npm run build and we saw how the JavaScript and HTML files were placed in the dist folder for distribution. So that wraps up this course. By now you should be familiar with all the key features within JavaScript to build great applications. It'll take a lot of practice and experience to master JavaScript and you can take a look at some of my other courses on Pluralsight. Rapid JavaScript Training is a course that rapidly takes you through most of the JavaScript language and features. This is a great way to go more in-depth on some of the subjects covered in this course and just review some of the key concepts. Also there's Rapid ES6 Training. This is specifically for the ECMAScript 2015 version of JavaScript whose nickname is ES6. This will take you through most of the main features in that release. And another one of my courses is Object-oriented Programming in JavaScript, ES6. This goes more into using classes to build a full application using JavaScript. And that wraps up this course. Good luck with your JavaScript projects. Course author Mark Zamoyta Mark started in the developer world over 25 years ago. He began his career with a Bachelor of Science in Computer Science from St. Johns University. After spending 10 years on Wall Street working... Course info LevelIntermediate Rating (83) My rating Duration3h 0m Released26 Jul 2018 Share course