What do you want to learn?
Leverged
jhuang@tampa.cgsinc.com
Skip to main content
Pluralsight uses cookies.Learn more about your privacy
Rapid JavaScript Training
by Mark Zamoyta
Learn JavaScript rapidly in a direct question and answer format. You'll see hundreds of examples which cover most aspects of the language.
Resume CourseBookmarkAdd to Channel
Table of contents
Description
Transcript
Exercise files
Discussion
Learning Check
Recommended
Introduction
Introduction
Hello, my name is Mark Zamoyta. When I learned JavaScript initially I was already a professional software developer with about 10 years of experience in C and C++ and I knew some Java. I didn't need anyone to tell me what a variable was or how a for loop worked, I just needed someone to point out the JavaScript way of doing things. I wanted a very rapid review of the language as a whole, showing off JavaScript's unique features. So welcome to Rapid JavaScript Training. This is the course I wish I had when I was getting into JavaScript programming. I create this course for two groups of developers. Professional programmers who want to learn JavaScript in a rapid, direct way and mainly those are programmers coming from another language, and also anyone who has taken a fundamental JavaScript course and wants to quickly learn more about the language. If you're not already familiar with JavaScript, I would suggest this Pluralsight course, JavaScript From Scratch by Jesse Liberty. That course will get you started and then my course will cover the language in much more detail. This course has a unique format for a Pluralsight course; it's done mainly in a question and answer format. It's designed so that you can pause video playback, look at some source code, and try to figure things out before I give a short explanation of the answer. Here's an example, this example slide is from the operator's module and I'm going over the plus sign as a operator. This is the kind of code I will not be spending a lot of time discussing, it's very simple and I'll get straight to the point. The question for the slide will appear here. After seeing the question, you'll have about 2 seconds to pause the video if you need to work things out on your own. Hopefully you don't spend too much time figuring out what 5 + 3 is, and then the answer will show up here. In most cases the source code will write the answer out to the console. This way you can easily copy and paste the source code from my PowerPoint slides if you subscribe to the course files, and you'll get the answer yourself in a browser's console. Here's another example slide, what is 5.1 + 3.3? What shows in the console? And remember, if you need to work this out you'll have about 2 seconds to hit the pause button before the answer shows. I'm sure many of you guessed 8.4, but the answer is actually 8.3999 and so on. This is a source of many bugs in JavaScript programs, so I'll slow down a bit in slides like this to explain what's going on. If you compared the variable total to see if it was equal to 8.4, you'd get false. And this course will cover why this happens and what to do about it. This course contains hundreds of slides like these, covering the JavaScript language step by step. I used the latest version of Google's Chrome browser to verify the answers and in a few rare cases I used Internet Explorer to point out some browser differences. Let's take a quick look at this course's 11 modules. After this introduction, module 2 will cover JavaScript basics. This covers much of JavaScript at a high level with subsequent modules going into much more detail. Module 3 covers variables, types, and scope. Module 4 covers operators. Module 5 is about arrays and other reference types. Module 6 covers objects, JSON, and prototypes. Module 7 is all about functions. Module 8 is on the Browser Object Model and Document Object Model. Module 9 is about writing even handlers. Module 10 goes over some built-in objects and global functions. And finally, module 11 covers miscellaneous topics and tools that will help us out as JavaScript developers. Before we get started with the question and answer slides, I'm going to point out a few easy ways we can play and experiment with JavaScript on the web, we'll see that in the next video.
Experimenting with JavaScript on the Web
The best way to learn JavaScript, or any programming language, is by creating many, many example programs. You could use your editor or IDE of choice, of course, but I want to go over two easy ways to quickly write JavaScript programs on the web. There's jsfiddle.NET and plnkr.co. You can enter the source code from this course's videos in these sites and if you subscribe to the course files you can simply copy and paste examples from the PowerPoint slides. We'll start off at jsfiddle.NET. Here we have the JavaScript pane where you can enter your source code. I'll paste in an example from the introduction. Here we have the HTML pane where we can add markup to the document body if needed. I'll simply add a header. I'll click the Run button right here or press Ctrl+Enter. And we can see our webpage here in this panel. It only shows the markup because we logged the variable out to the console. Here's the console, which is part of a browser's developer tools and it's usually open by pressing F12. You may have to click on the Console tab in Chrome or whatever other browser you're using. Here you can see the output of the console.log function call. In Chrome you can clear the console by right clicking and selecting Clear console. Let's also look at Plunker at plnkr.co. We can start out by pressing the Launch the Editor button. Here is a list of files and we're interested mainly in script.js to enter JavaScript code. If you need to enter markup, you can modify index.html. I went through the same code from the last example and Plunker will go ahead and execute it immediately. There's no need to press a Run button as in jsfiddle. Just make sure you select the live preview icon to see your webpage. Here we see the console output and if we need to we can clear the console again. If you ever need to refresh the page, use this refresh button right here. So we're all set to go. In the next module we'll look at JavaScript basics.
JavaScript Basics
Introduction
Welcome to this module titled JavaScript Basics. My name is Mark Zamoyta. In this module we'll touch on the fundamentals of the JavaScript language. We'll go into much more detail on each item throughout the remainder of this course, but let's get a quick overview of JavaScript as a whole. In this module we'll start off by looking at the script tag, that's the HTML5 tag that lets us include JavaScript within a webpage. Then we'll look at variables and types. And again, this is at a very high level. We'll take a look at functions at a high level and we have a whole module dedicated to functions later on in this course. We'll take a look at conditionals for statements such as if and switch. We'll take a look at loops, things such as for loops or the for in loop, and while. And we'll wrap up the module with some JavaScript usage notes. This will cover things such as comments and the end of line character, the semicolon, and some other miscellaneous topics. So let's take a look at the script tag.
JavaScript in Web Pages
Let's take a look at using JavaScript within web pages. We use the HTML5 script tag in order to embed JavaScript within a web page or to point it to a JavaScript file. We use the src or source attribute on the script tag in order to specify which JavaScript file to load. There is also a defer attribute that we can use to delay the loading of a file and we'll also look at the noscript tag, which can contain markup that'll show if JavaScript is turned off or if the browser is incapable of displaying JavaScript. So here we have a very fundamental web page. We're not going to go into HTML in this course, but I'll just show that we have our DOCTYPE tag, an html tag, a head, and a body. Within the head we place the script tag and there's a single line of code within the script tag. So what is going to show in the console? We'll see the word Hello with the exclamation point. Any code that gets placed within a script tag in HTML will execute immediately. Here's another simple HTML page and before we had our script tag in the head, but now we have it in the body. And we're calling console.log in body. So what's going to show in the console? In Body, even though our script tag is in the body section now, it's still going to execute when the browser parses it. And this is actually the preferred place for a script tag; it's at the very end of your body section. This way your page can load and display within the browser while the JavaScript is being parsed and executed. Now we're going to take a look at using a separate JavaScript file. In this top section, app.js is our JavaScript file and it has a single line of code. Now if we look in our index.html file, we have our script tag and we're using the source attribute and you'll notice that the source attribute is pointing to our app.js file in the js directory. What's going to show in the console? The console will show in app.js. When the browser processes the script tag, it's going to look at that source attribute and load the corresponding file and execute it immediately. So within our js file, our app.js file will execute and it will show in app.js in the console. Here we see a few new things, we still have our app.js file, but in index.html we're doing something different with our script tag. First of all, we're using the type attribute, which is using the default type, text/JavaScript, and that just tells us what type of source file we're looking at. Text/JavaScript is the default in all the major browsers, so we can usually just leave that out. But look at what we're doing, we're loading a source file and we're also including some code within the script tag. So there are two different ways we're loading code, through the source attribute and directly within the script tag. What's going to show in the console? It's going to show in app.js. Notice that it doesn't show hello. If we're using the source tag, the browser is going to ignore all of the code within the script tag itself, it's only going to load the source file, and that's why hello doesn't show up in the console. Let's take a look at this example. Looking at the script tag we can see that the script tag itself is being treated more like an XML tag. We're not ending it off with a /script final tag. We're ending it off the way we would end a simple XML tag and this is a common bug. What's going to show in the console? We're going to get an unexpected end of file. The problem is that HTML is not XML. When we're working with scripts we always need to end it with a final tag, /script. Now this will work in some browsers. I think it works in Chrome, but it doesn't work in all the browsers, like it won't work in Internet Explorer, for example. So always be careful, end your script tags with /script as its own tag. And here we can see the proper way to end the script tag that we talked about in the last slide. So looking at this example now, we have two JavaScript files, app.js and salesorder.js and this is a much more common example. You're going to see tons of JavaScript files included within your HTML files. It's very rare that you'll have just one. So looking at our index.html file, we have two separate script tags, one for each file. What's going to show in the console? In app.js, in salesOrder.js. So these files will be processed in order. It'll take the first script, wait for it to load, and then execute it, and then read the next script, wait for it to load and execute it. And with these script tags, it's always important to know that they will be executed in order. Here we have a similar example except we have a defer attribute on our script tag. The second script tag is fine, there's no defer tag, it's only on the first one. So what's going to show up in the console? We get in salesOrder.js and then in app.js. So you can see that the order is reversed. The defer tag put a delay on the browser executing app.js. So salesOrder.js went ahead and loaded and compiled and executed and then when we got to the end of the body it went ahead and processed app.js. This is something that you might run into in some existing code, but it's generally not a good idea to use defer. The reason why is that in some HTML files it might not be deferred while in others it will be deferred and this can cause some confusion for the developer. It's better just to use the source attribute by itself without defer and have the developer get control over how things load. If you need an optimization, it's better to build that into some sort of build process with Grunt or Gulp. Here we have an example that uses the noscript tag. You'll notice we have a simple h1 tag in the middle of noscript. So what shows in the web page when JavaScript is turned off or JavaScript isn't available? The web page will show, this application requires JavaScript. It'll show that h1 tag. Generally it's useful to put in a noscript tag to notify people that they need to turn JavaScript on or to offer some kind of user interface to a device that doesn't offer JavaScript.
Variables
Let's look at JavaScript variables from a very high level. We're going to look at the fundamentals of assigning variables and how they're used. We'll take a look at the undefined keyword, and that's its own data type as well. But we'll see how that's used with variables. We'll take a look at the primitive types, things such as strings, numbers, and Booleans. And we'll take a very high level look at object and function types. Again, this is all introductory and everything will be covered in much more detail later in the course. Here we're using the var keyword to create a new variable called orderId and we're assigning the number 9001 to the orderId. What's going to show in the console? We'll get 9001. This is a very simple example of using a variable. And here we're setting orderId to a string, ORD-9001 in double quotes. What's going to show in the console? We'll get our string, ORD-9001. So we've seen variables holding numbers and now a string. And here's a special property of JavaScript variables, we're creating orderId as a variable and we're setting it to a string. Next we change our minds and we set it to a numeric type, 1201. What's going to show in the console? 1201. In JavaScript the variables are dynamically typed. The type of a variable is definite, but it can change throughout the course of execution. This isn't a best practice, but you do see it all the time. In this example orderId started off as a string, but later was assigned to a number and changing types like that is fine. Here we're declaring variable called orderId, but we're not assigning any value to it. What's going to show in the console? Undefined. When a variable is not initialized in JavaScript, it'll always be set to undefined. Now here's a case where we're leaving off the var keyword. We're just setting orderId to 9001. But orderId is not declared as a variable anywhere. What's going to show in the console? 9001. Even though we left off the var keyword, JavaScript noticed that and created a new global variable for us. And generally that's a problem. We want to have control over our global variables, we don't want JavaScript creating them for us. Let's take a look at the next example. Here we're specifying a string called use strict, and this is a feature of ES5 where we can enter strict mode. We'll cover strict mode throughout this course and we'll go into more detail at the very end of the course. But strict mode changes the way some of JavaScript's functionality works. So here we're in strict mode, just by specifying that string on its own line, and we're setting orderId to 9001. What's going to show in the console? We'll get a runtime error: variable undefined in strict mode. So strict mode was created to handle this kind of bug. JavaScript isn't going to be able to create global variables for us in strict mode. So when execution gets to this line, orderId = 9001, that's where we'll get our runtime error. OrderId just doesn't exist and JavaScript is not going to create it for us. Now let's look at some data types. We're creating orderId and we're initializing it to 9001. And notice that we're using the typeof operator. What is the typeof orderId. What will show in the console? It's a number, and that's one of the primitive data types within JavaScript. The number can be an integer or a floating point number, they're both specified by the type number. And here we can see that we're setting orderId to 9001.01. That's a decimal or floating point number. What is the type of orderId? What will show in the console? Number. So it's important to know that whether we're working with integers or floating types, JavaScript sees them each as a number. Here we're setting orderId to a string with the double quotation marks. And again, we're going to log out the type of orderId. What will show in the console? String. String is another primitive data type. Here we're setting isActive to true. What is the type of isActive? What will show in the console? Boolean. Boolean is another one of the primitive data types in JavaScript and those are the three key ones that we just saw, number, string, and Boolean. Now here we have a variable that we're declaring called isActive, but we're not initializing it. What is the type of isActive? What will show in the console? Undefined. So undefined is a value that we can use, but it's also a type in and of its own. So the type of an uninitialized variable is always undefined. Here we have a simple object. We'll cover JSON notation later in the course in much more detail, but we're creating an object called order and it has two properties, orderId set to a number, 9001, and isActive set to true. What is the type of order? What will show in the console? Object. So object isn't considered a primitive data type, it's more of a complex data type, and it's probably one of the more common types we'll work with in JavaScript. Here we have a variable called cancelledOrders and we're setting it to an array of 3 numbers, 9001, 9002, and 9003. We'll cover arrays later in the course, but what is the type of cancelledOrders? What will show in the console? Object. There is no fundamental data type called array. When we create an array its type is an object and that's useful to know and later in this course we'll see the proper way of determining whether a variable is an array or not, but for now just know when we create an array the data type is actually an object. Here we're setting a new variable called order to null. What is the type of order? What will show in the console? Object. This is a strange quirk of JavaScript. It's almost a throwback to the C language where null was used to specify an empty object and that's how it's used in JavaScript too. When we set order to null we're saying order is an object, but it's empty, it has no fields or properties. So even though order is set to null, JavaScript is treating it as a type of object. Here we have a simple empty function called cancelOrder and there's no body to it. What we're interested in is seeing what is the type of cancelOrder? What will show in the console? The answer is function. We'll see later in this course how functions operate a lot like objects, but they do have their own type called function. Type of cancel order is function.
Function Fundamentals
Let's look at function fundamentals in JavaScript. In this video we'll look at declaring functions, we'll look at passing arguments to functions, we'll look at getting returned values out of functions, and we'll look at the difference between a function declaration and a function expression. Here we have a function called printOrder. And we call this a function declaration. We're declaring printOrder and it's going to be a global function. On this line we're calling printOrder and notice the open and closing parenthesis. This will execute the function. What will show in the console? It'll show printing order. So printOrder becomes reusable code that we can call over and over again by specifying printOrder and the parenthesis and that's the most simple type of function we can have. Here we have an example of passing an argument to printOrder. We can see that now within the parenthesis we're accepting an orderId. When we call printOrder passing it a string of 9002, that 9002 will be passed to that function. And notice how we're printing out printing order and we're adding the orderId to it and that's all going to console.log. What will show in the console? Printing order: 9002. So our orderId becomes pretty much a local variable within the function. And it gets initialized to 9002 because that's how we're calling it. Here's an interesting example that's pretty unique to JavaScript, we're calling a function called printOrder and we're passing it 9002 as a string, and the quirk about this is that we're calling the function, but the function hasn't been declared yet. We're declaring the function after we call it. So this is the same example as the last one, except we're calling the function before we declare it. What shows in the console? The function actually works and it shows printing order 9002. And it's very important to understand how JavaScript processes this kind of code. JavaScript works in two passes, in the first pass it will create any variables or functions, and we'll go into this in a lot more detail in the module on functions where we talk about hoisting, but in this example, in the first pass it'll see a function called printOrder before anything gets executed. So it'll know that there's a global function called printOrder, and then when it comes time for the second pass, where the execution happens, our first line of code will work fine. PrintOrder already exists as a global variable by the time the second pass occurs and execution begins. So it's always helpful to look at JavaScript code in terms of two passes, the first pass will pick up any global variables or declarations and the second pass will begin execution. Here we see a function called calculateTotalPrice, that's getting declared, and it's accepting two arguments now, quantity and price. We'll call this function calcTotalPrice passing it 2 and 4.00, $4.00. What shows in the console? 8. So when the function gets called and executed, quantity will be set to 2 and price will be set to $4.00 and the calculation that gets printed is quantity times price, which will be 8. Now here we're declaring a function called calcTotalPrice that accepts three arguments, quantity, price, and currency. And just as an example here, let's log out currency within this function. We'll call the function with only two arguments. Quantity will be set to 2 and price will be set to 4. But we're missing the third argument, what shows in the console? We'll get undefined. Notice that we don't get an error. Most other languages will give us some kind of error saying that the arguments don't match up, but in JavaScript it's going to take any extra arguments and assign undefined to them. And this is a good way to pass optional arguments to a function. You know that they'll get set to undefined automatically without an error being thrown. Here we're declaring a function called calcTotalPrice, passing two arguments, but we're using the return keyword. We're going to return the quantity times price. You can see that we're declaring a variable called totalPrice and we're setting that to calcTotalPrice 2, 4. What shows in the console? The console will show 8. The way to get information out of a function is with this return keyword. So we simply assign the function call to a new variable and that way totalPrice will hold the number 8 after execution. It's usually not to useful to have a function unless you're going to call it multiple times over and over and over. So here we have an example of that. We have calcTotalPrice and we're going to call it twice. We're going to assign it to totalPrice and log that out to the console and then we're going to reset totalPrice to another function call to calcTotalPrice, but we're going to pass different arguments and then we'll log that out to the console. What shows in the console? 8 and then 9. For the first function call it'll calculate 2 times 4, we'll get 8, and then second function call will calculate 3 times 3 and we'll get 9. Here we have a function declaration called getOrder and we're not going to return anything from it, but we are going to create a variable called order and assign it the result of that function call. What's going to show in the console? Undefined. So if a function does not return a value, JavaScript will assign undefined as the return value and that can either be done on purpose or as a bug. You just always have to be careful if you actually want to return something, use the return keyword with the proper value. Here we have a function expression, which is different from the declarations we've been using before. Previously everything has been put as a function into the global scope, but here we're using a variable, and assigning a function to the variable. We're declaring activateOrder and we're assigning it a function. The function doesn't have a name, it's an anonymous function and it's simply going to write out a string to the console. But this function is held in this variable, activateOrder. So what does the type of activateOrder? What shows in the console? It's a function. So a variable can hold primitive data types, other values that we've seen, and also functions. And this is very common in JavaScript. You're going to see functions assigned to variables very often. And these are called function expressions. So here we have a function expression, the variable activateOrder is now being set to a function. This time instead of using typeOf to see what it is, let's execute it. We can call activateOrder with parenthesis. What shows in the console? We get order activated. The function will execute. So while this might seem a little bit strange at first, assigning a function to a variable, it's extremely common in JavaScript and after working with it for awhile it becomes second nature. To execute the functions stored in the variable, just be sure to add the parenthesis. Here we have another simple function expression and we're calling activateOrder, but notice the parenthesis are missing. What shows in the console? Well we don't get anything in the console, we're not executing the variable. ActivateOrder on its own without the parenthesis is simply a reference to the variable that JavaScript can ignore. So always be sure to use the parenthesis when you're working with variables that are storing functions.
if and switch Statements
Let's take a look at it and switch statements in JavaScript. In this video I'll take a look at the if keyword, we'll look at if else statements, we'll look at the switch statement and its cases, and we'll look at advanced cases. JavaScript can do a few things that some of the traditional programming languages can't do with cases. We'll take a look at that in this video. Here we have an example where we're setting a total variable and a free shipping variable. And we have an if statement. If total is greater than equal to 50, we'll set freeShipping to true. What shows in the console? True. The value of total is greater than or equal to 50. So this is called a conditional statement, if takes a condition. If the condition is true, the following code will execute. If it's false, the following code will not execute. Let's take a look at this example, it's slightly different. We're setting total and freeShipping, but the condition is different. If total is greater than or equal to 100, then freeShipping is true. What shows in the console? We get false. Here the condition fails and freeShipping remains at its initialized value, false. Here we have another similar example, except we add an else clause. If total is greater than or equal to 100, we'll execute this line, otherwise we have the else statement, we'll execute this line. What shows in the console? We get false. The total is actually less than 100, so the code after the else statement will execute. FreeShipping will be set to false. Normally what you see after an if or an else statement are several lines of code that should execute and those are wrapped in curly braces. We can see that here. If total is greater than or equal to 100, we'll execute these two lines of code between the braces. What shows in the console? We get 0. If total were greater than or equal to 100, savings would be 29.99, but that's not true. We're going to hit our else block of code and savings is going to be set to 0. Here's an error that you might run into, it's very similar to the last example, but look at this semicolon right here. A lot of times it's common to put a semicolon after a block of code such as a function declaration. What shows in the console? We get a syntax error. We need to leave the semicolon off, that way the else can associate with the previous block of code and the if statement. So always remember, if we're using else clauses, leave off the semicolons. Here we have an example of an if statement, an else if, and an else. If the order type is business, we're going to set our shipMethod to FedEx, and then we have an else clause followed by an if immediately. Else if orderType = personal, shipMethod = UPS Ground. And finally, we have an else on its own, shipMethod = USPS for United States Postal Service. What shows in the console? We get FedEx. OrderType is equal to business. So our shipMethod is FedEx. There's no need to execute the else if or the final else. Here we have similar logic, but it's broken out with a switch statement. We're going to do a switch on orderType and notice we can use hard coded strings. If orderType is business, the shipMethod will be FedEx, that's the first case. And the second case, if the orderType is personal, the shipMethod will be UPS Ground. And we have a default where we'll set the shipping method to USPS if none of the other cases fit. What will show in the console? FedEx. OrderType is being set to business on the first line, so that's the case that will execute. None of the cases or the default apply. Here's a common bug and it's something to always watch out for in your switch statements. This is similar to the last example, but you can see I commented out the break statement. This will cause code execution to fall through, so at the start we're setting orderType to business. So the case for business will get executed and shipmethod will be set to FedEx, but now the break is commented out. After all this code executes, what shows in the console? We get UPS Ground. Because we commented out the break and in real life it would probably just be forgotten altogether, like the developer would forget to put in a break, we'll get this fall through functionality. Sometimes the fall through functionality would be desired, but you should put a comment in noting that it's intended to fall through. In this case it's a bug, the shipMethod is being set to UPS Ground because we don't have a break statement. Here's another example of a switch statement, notice that we want case business and case personal to be handled by the same code this time. We can just line them up like this. Notice that we're setting orderType to unknown at the start. What shows in the console? USPS. The orderType is unknown, so it will go to the default handling. We'll set shipMethod to USPS by default. None of the other cases were hit. Here's another example of a switch statement, and notice that I took out the default. We're setting orderType to unknown at the beginning. What shows in the console? Undefined. When we declare the variable shipMethod, we're not initializing it, so remember it gets set automatically by JavaScript to undefined. And in this case our switch statement is useless. There aren't any cases to cover our value, so when it comes time to log out shipMethod we get undefined. Here's a more complex switch statement that is pretty unique to JavaScript. You won't find this capability in some of the other programming languages, such as C or C# or others. We're going to pass in true to the switch statement and now all of our cases become expressions that can be evaluated. In the first case we evaluate if orderTotal is greater than or equal to 50 and orderTotal is less than 75. We'll set the discount to 10. And the other cases are similar. We're going to check greater than or equal to 75, less than 100, and we'll check for greater than equal to 100 and we'll have a default. So notice we're setting order total equal to 99 99. What shows in the console? 20. This case here will get executed because the order total is greater than equal to 75 and the order total is less than 100. Using this type of switch statement is fine in JavaScript, but more normally you'll see this code implemented with if and else if statements.
while and do...while Statements
Let's take a look at while and do while statements in JavaScript. While is used to test a condition and execute code as long as that condition is true. Do while is a little bit different. In a do while loop you'll always execute the code at least once. And then the condition will be checked after that code is executed the first time and subsequent times. Let's look at examples. Here we have two variables, lineItemCount and currentItem and we have a while statement right here. While currentItem is less than lineItemCount we're going to execute this code. Notice at the end of the loop we're incrementing currentItem, so at some point this while condition will fail. What shows in the console? item: 0, item: 1, item: 2. So this will continue to loop and currentItem will continue to increment until it reaches 3, at which case the while statement is finished. Here we have another loop, while currentItem is less than lineItemCount, we'll execute this code. Notice that we're calling currentItem++, this will increment currentItem each time through the loop. We'll cover operators in much more detail in a later module. What shows in the console? Item: 0, item: 1, item: 2. So in a loop it's always important to see how the variables change and it's very easy to miss these kinds of increment and decrement operators. Here we have another example, while the currentItem is less than the lineItemCount, let's log out this string. Notice that currentItem doesn't change at all in the loop. What shows in the console? It'll show item: 0 over and over endlessly. At some point your computer may run out of memory where it would stop, but it is possible that it would go on forever. Here we have a do while statement. In a do while statement we're always going to execute the code and then we check the condition afterwards. What shows in the console? Item: 0, item: 1, item: 2. So if it's guaranteed that you'll need to loop at least once, use a do while statement. Here's another interesting example, we have a do while, but notice that currentItem is being set to undefined. This could happen in your code where you're going to access an undefined variable within a loop. But what do you think is going to happen? We're going to log out item, currentItem, and then we're going to use currentItem as undefined in a condition. What shows in the console? We get undefined. We'll learn more about working with undefined values and strings later in this course, but when we add item: to an undefined variable we get undefined and that's what gets logged out. And then the operator on an undefined variable, that'll get ignored and it will remain undefined and our condition will also result in undefined. It'll evaluate to false because of the undefined value. So the point here is always make sure that you're working with valid data. If something is undefined or null, you really want to check into those edge cases and make sure that it's either impossible to happen or that you have that case covered within a loop.
for and for...in
In this video we'll take a look at for loops, those are common in pretty much every programming language. We'll look at the break statement to exit a loop, we'll look at the continue statement to go to the next iteration of a loop, and we'll look at the for in loop, this lets us look in detail at the properties of an object. Let's see some examples. Here we have a simple for loop. Here we're declaring a variable i and initializing it to 0. This occurs once at the beginning of the loop. Next is out condition. As long as i is less than lineItemCount we'll execute the code within the loop. And after each iteration of the loop we'll execute this, i++, we'll increment i. So what's going to show in the console? We'll get 0, 1, and 2. So for this loop we'll execute the console.log 3 times. Here's another similar example. You'll notice that it starts with a semicolon, so there's no initialization for the loop, but we are initializing the variable i before the loop even begins. What shows in the console? We get 0, 1, and 2, just like before. You'll see this once in a while where we don't need to initialize anything and we can start off the for loop with the semicolon. Here's another similar example and this isn't a good programming style, but you'll notice that we're not executing any code at the end of the for loop. Instead of specifying i++ in parenthesis, you can see that we're doing it within the body of the for loop. So what's going to show in the console? 0, 1, and 2. So this is a similar loop to the others, but most developers would prefer to see the i++ on the for line. Here we have another for loop, but you'll notice we have a conditional within the for loop where we'll break out of it, if i is equal to 1. So what do you think will show in the console? We'll get 0 and 1. As soon as i = 1, we'll break out of the loop and there's no more code to execute after the for loop. In this example we have a conditional within the loop if i is equal to 1, we want to continue. Continue will stop execution of the body of the loop and execute this code, i++, and then continue the loop. So what's going to show in the console? 0, 2, 3, and 4. So we're going to skip 1. If i is equal to 1 we're going to continue and we won't log out the number 1, but we will log out each other number. Here's a more complex example of nested loops. We have a for loop within a for loop and we can actually specify a tag with continue. Here we're calling continue outerLoop and that will just jump back out to the outerLoop, as we can see right here. But that'll only happen if j is equal to 1. What shows in the console? Well this is tricky, but nothing is ever going to show in the console. We're always going to execute our continue outerLoop and then as the outerLoop continues the innerLoop will always kick us out, so we'll never reach this line of code where we log out i. Let's look at a for in loop right now. We'll start off by creating an object called lineItem and we're using JSON notation. We have properties called product, quantity, and price. So we have three properties that we're defining in JSON. Then in the for in loop, we specify the key word for parenthesis and we specify a variable that we'll use to represent the current field or property. So we have var field in lineItem and this will loop through each user defined property within the object. So what shows in the console? We'll get product, quantity, and price. Those are the three field names within the object. Here's another more useful example of the for in loop, again we have our lineItem object with product, quantity, and price fields. Now we're going to specify for (var field in lineItem). But here we're going to log out something different. We're going to log out field, which is the name of the field, but we're also going to access the value of the field with lineItem What's going to show in the console? We'll get product: Widget 1, quantity: 4, and price: $9.50. So this is very common in for in loops. We need to access not only the field, but the value of the field, which we can specify right here, lineItem
JavaScript Usage Features
Let's take a look at some JavaScript usage features. We'll take a look at case sensitivity, JavaScript is case sensitive and we'll see some examples of that. We'll take a look at comments in JavaScript and we'll take a look at identifiers and some of the symbols that we're allowed to use within identifiers. So here we have two simple lines of code, what do you think is going to show in the console? We'll get a reference error, orderId is not defined. You'll notice that the variable we have is called orderId with a lower case o, but we're printing out an uppercase O for OrderId, so JavaScript is case sensitive. And here we're declaring a function called submitOrder and we're trying to call that function. What do you think will print out in the console? Again we'll get a reference error, submitorder is not defined. You see that we have a capital O in our function, but we're calling it with a lowercase o for order. So again, it's always important to use the right case. JavaScript is case sensitive. Let's take a look at some comments. We can comment out multiple lines with the standard /* and */ syntax. We can also comment out single lines with a double slash. So what do you think is going to show in the console? We'll get a 2. This line is the only line that's not commented out. Here's a similar example where you can see that we're embedding comments. We're commenting out multiple lines with the /* or */, but then we're also embedding a similar comment here. What do you think is going to happen in the console? We'll get a syntax error, unexpected token ). So as you can see, we're not allowed to embed comments this way. In this example we're creating a variable called @product, at product, and then we're logging it out. Do you think this is valid in JavaScript? Nope, we get a SyntaxError. Variable names can only begin with symbols, such as the dollar sign and the underscore. Any other symbol is not allowed at the beginning of an identifier, so only dollar signs and underscores at the start. How about this one where we have a variable 2product, beginning with the number 2. Do you think that's valid? What shows in the console? We also get a SyntaxError. So we're not allowed to start an identifier with a number. Identifiers need to start with either a letter or the underscore or dollar sign symbols. How about this one, we're creating a variable, $product, and then we're going to tack on X2, then we're going to log out the product, but notice there are no semicolons. What do you think will show in the console? This code will run fine, we'll get PRD-4000X2, and that's one of the features, if you want to call it a feature, of JavaScript. JavaScript will determine where it expects an end of line to be and put in the semicolons for you. Most of the time this works out fine, but it's definitely a best practice to put in your own semicolons, this makes it crystal clear what your intention is.
Summary
In this module we looked at the script tag for embedding JavaScript within a web page. We took at look at JavaScript's variables and types. The primitive types were things such as strings, numbers, and Booleans, those are the most common. We reviewed functions and passing data into a function and returning data from a function. And we took a look at conditional statements, such as if and switch. We examined loops such as for loops, while loops, and do while loops, and we wrapped up the module by looking at some JavaScript usage notes. We looked at using comments, semicolons at the end of lines, and case sensitivity.
Variables, Types, and Scope
Introduction
Hello this is Mark Zamoyta and this module is titled Variables, Types, and Scope. In our last module we went over JavaScript in high level detail, but now we're going to start to get more specific with variables and types and we'll also talk about global, function, and block scope. We'll start off this module talking about hoisting. Hoisting is rather unique to JavaScript. And it's a source of a lot of bugs, so we want to make sure we understand this thoroughly. Next we'll look at the primitive types in more detail. The key primitive types are strings, numbers, and Boolean values. We'll take a look at undefined and null and when we should use them and what the exact differences are. And then we'll start taking a look at scopes, we'll take a look at global scope in detail, we'll look at function scope, and we'll look at block scope. JavaScript doesn't have block scope in a similar way to other languages, but there is a way to simulate it in a try-catch finally construct, so we'll take a look at this as well.
Hoisting
Let's take a look at hoisting in JavaScript. Hoisting refers to having access to variables before they're even declared, and this is a strange concept. It doesn't exist in the other major languages. And to understand hoisting, we kind of have to understand a little bit about how JavaScript compiles. And we can view it as compiling in two passes. In Pass 1, all declarations are located and identifiers are known by the compiler. Nothing is going to get executed, we're just going to look for any identifiers that get declared in Pass 1. In Pass 2 we can view this as where execution occurs. Because all variables are known from Pass 1, they may be accessed before they're declared in the source code. So let's look at what hoisting means. The word hoisting is used to describe this behavior because it says if the declarations are lifted or hoisted to the top of the function before execution. And during hoisting it's important to know that hoisted variables are initialized to undefined. So let's look at some examples and we'll start with this, let's log out productId. Now productId hasn't been declared. What's going to show in the console? We'll get a ReferenceError: productId is not defined, and we've seen that before in this course. Let's go to the next one. So now we're logging out productId as in the last example, but then we're declaring productId after it's logging out. We're setting productId to 9000. What shows in the console? We get undefined. So we're not getting the error anymore, and this is really strange behavior the first time you see it. What has happened is in the first pass the compiler sees that we're declaring productId, so now the compiler is aware of it. So in the second pass, when we actually execute console.log with productID, the compiler knows about that global variable, but it gets set to undefined. It doesn't get set to 9000 until this code actually executes in the second pass. And that's really what hoisting is all about, it's about scanning the source code, looking for declarations, and then having access to those variables. A lot of developers will never use hoisting. They'll always declare them up front and generally that's what I do as well. Hoisting can be confusing and it's the source of a lot of bugs. Here's another example of hoisting. The first line sets total to price times quantity, but after that we define price and quantity. What's going to show in the console? We get not a number, NaN. If you're not family with this, we'll cover it later in the course, but for now just know that whenever you try to work with numbers and one of the number is undefined, the answer we'll get from the evaluation will be not a number, NaN. So why is this? When we execute the first line, price and quantity are known because of hoisting, but they're not set yet, they're set to undefined. And undefined multiplied by undefined is not a number. And that's our answer. And hoisting works with functions as well. Here we're calling showProduct, but we haven't even declared it yet. We declare the function showProduct and we're going to log out a message. What do you think shows in the console? Showing a Product. So the function executes fine. In the first pass the compiler will find out about that function and be able to execute it in the second pass, and that's another example of using hoisting with a declared function. So in this example, we have a function expression, which is different from the last example where we had just a simple function being declared. We're going to call showProduct, but later on we're going to create that variable called showProduct and assign it a function. What do you think will show in the console? We'll get a TypeError: showProduct is not a function. So what's going on here is that in the first pass showProduct is going to be hoisted, but it's going to be set to undefined. So when we call showProduct, it's not really a function yet, it's set to undefined. It's not until the second pass when we execute this line that showProduct will become a function. So the way to avoid that is to avoid hoisting altogether. Here we have our function expression, we're setting var showProduct equal to a function and then we'll calling it. What shows in the console? We'll get our message showing a product. So if you are going to work with function expressions like this, always declare them before you call them as functions. We want to avoid any hoisting problems. Again, just to show you a function declaration as opposed to function expressions, function declarations do get hoisted properly. What shows in the console? We get our message, Showing a Product. So if we assign the function to a variable it won't get hoisted properly, it won't be able to be called as a function. But in this case, we're just creating a global function called showProduct and everything works fine.
Numbers
Let's take a look at numbers in JavaScript. Number is a primitive type. Here we have two examples of numbers, quantity = 2, that's being used as an integer, and we have price = 0.99, that's being used as a floating point number, and each type of number is specified by the data type called number. What's going to show in the console? We'll get 1.98. We're doing a simple multiplication of quantity times price. Here we're setting price to 0.99, but we're putting it in double quotes, so we're treating it as a string. Even though it's numeric, what is the type of price? What's going to show in the console? It's a string. So JavaScript isn't going to do any numeric conversion for us if we're using a string. In some cases it will and we'll see that later in the course, but here we have a string. We can also work with octal numbers in JavaScript. And it's very rare to use octal numbers, but I'm just putting this in for completeness. If a number begins with 0, it'll be considered octal. Octal numbers have a base of 8. So what's going to show in the console? We'll get 56, which is octal 070. Now octal number ranges from 0 to 7, but here we're setting variable oct to 088, so it's an octal number with invalid digits. What do you think will show in the console? We'll get the number 88. So if you do work with octal numbers, this is very strange behavior. If it's not a valid octal number it'll treat it as a decimal number. So what happens if we use strict and we start working with octal numbers like this? What do you think is going to show in the console? We'll get a SyntaxError. In strict mode we're not allowed to work with octals at all. By beginning a number with 0, things can get very confusing and JavaScript can start working with octals where the developer doesn't even know what an octal number is. So when working in strict mode, octals just aren't allowed. Hexadecimal numbers are a lot more common. And a hex number can begin with 0x. So what do you think will show in the console? We'll get 16. Hex 10 is equal to 16 in decimal. Here we have variable value being set to 3.2e4. The e represents the number 10 raised to the 4th power, in this case. So this is a shorthand notation for floating points, raising 3.2 to 10 to the 4th power is the same as moving the decimal point 4 places to the right. What do you think will show in the console? 32000. So we have 3.2 and we move the decimal 4 places to the right. Here we have a similar problem, 3.2e to the -4. That's the same as raising 3.2 to the 10 to the -4th power, which is equivalent to moving the decimal point 4 spaces to the left. What's going to show in the console? We'll get 0.00032. The decimal place is moved 4 spaces to the left, 10 to the -4th power. When working with numbers we also have access to a number object and we can access the max value field. What do you think shows in the console? We can have a very large floating point number. You can see here that it's set to 1.79 and so on, but at the end, we can see it's set to e308 or 10 to the 308th power, which is a pretty big number. And we also have a Number.MIN_VALUE that we can access. What do you think shows in the console? 5 times 10 to the -324th power. With numbers we can also do operations on some of these constants. What is Number.MAX_VALUE times 2? What shows in the console? We get infinity, which is another constant having to do with numbers in JavaScript. There are a lot of rules regarding infinity and I'm not going to cover all of those in this course. Just know that when numbers get too big, they'll be set to infinity. If they get too small, they'll be set to negative infinity, and we'll see some examples coming up. Here we're creating a new variable n and we're assigning infinity to it. What is the typeof n? What shows in the console? We get number. So the data type of infinity is still a number. Similarly, what if we set n to -infinity? What if we log that out? What will show in the console? We get -Infinity. So if you are working with infinity values, make sure you know the different between positive and negative and they exist on both ends of the number line. We can also access infinity and negative infinity in this way, Number.POSITIVE_INFINITY and Number.NEGATIVE_INFINITY. What shows in the console? We get our infinity constants, Infinity and -Infinity. This is just an alternative way to represent them based on the number object. Let's look at some mathematical operations involving numbers. Here we're declaring count, but we're not initializing it. It's going to be initialized to undefined, and then we're initializing price to 5.00. What's going to show in the console? We get NaN or not a number. Whenever JavaScript attempts a numeric calculation or evaluation, if one of the values is undefined, it's not going to throw an exception, it's just going to create the result as not a number, NaN, which is a special symbol in JavaScript. Most other languages will throw some kind of exception, so you really need to be careful for this when working in JavaScript. So we have our NaN symbol and what is the typeof NaN? Remember, NaN stands for not a number. What shows in the console? Number, and it's really strange the first time you see this. The symbol not a number is actually the data type number, and when you work with this for a while it starts to make sense because whenever you're performing a mathematical operation, JavaScript wants the answer to be a number and if it can't figure it out, it'll just set the result of the expression to NaN, which is still a type number. Here we're assigning the variable n to not a number. You portably wouldn't do that on purpose, but it could be the result of some expression in more complex code. And this is what we use to test if a number is set to NaN. We use the isNaN function. What shows in the console? We get our string, NaN with an exclamation point. So if you ever wanted to test a variable to see if it's set to not a number, this is how you do it, with this function.
Strings
Let's take a look at strings in JavaScript. Strings are another primitive type called string, all lowercase. Here we can see strings specified with double quotes or single quotes. Either one of these is fine. What's going to show in the console? We'll get Hello world! And JavaScript doesn't differentiate between double quotes or single quotes at all. They're both equal. So how about this example, we want to print out a string in double quotes called ("The order is \"In Progress\"") so we want to include quotes within our quoted string. We can escape them with the slash symbol. What shows in the console? The order is "In Progress" and in progress is in double quotes. So to show double quotes within a double quoted string, we just need to escape the double quotes that we want to show. And how about with single quotes, what's going to show in the console? Nike's Order. So just like with double quotes we can escape a single quote when needed. So here we're initializing product type to a string and a very common operation on strings is to access the length property. What's going to show in the console? 8 because the word hardware is 8 characters long. Notice that length is a property and it's not a function. We don't include the open and closing parenthesis after it, it's a property of string. And here we're setting product type and notice the leading and trailing spaces and white space. When we print out producType to the console, notice that we're calling the trim function on it. What do you think will show in the console? We'll get the word Hardware in double brackets with all the white space removed, and that's what the trim function does on a string. It will remove all leading and trailing white space. Now here's a common bug when working with strings. We have productType and we're setting it to Hardware again with some leading and trailing white space. And then we take productType and we call trim on it. Then we're going to log out productType within the brackets. What will show in the console? We'll get Hardware, but it's going to maintain the white space. One thing to keep aware of is that strings are immutable in JavaScript. They're not going to change by calling a function on them. When we call productType.trim as a function, we need to assign that to a new variable. So in this example the trim function call is useless, we're not doing anything with the result value. And the white space remains in productType. Here's another common function call on a string. What is productType.toLowerCase? What will show in the console? We'll get hardware all in lowercase. Likewise here we're going to take a look at productType.toUpperCase. What will show in the console? We'll get HARDWARE, all uppercase. So toLowerCase and toUpperCase are very common functions that we can call on strings.
Boolean Values
Let's take a look at Boolean values in JavaScript. Boolean, all lowercase, is another primitive type in JavaScript. So the key three primitive types, we've already looked at number, string, and now Boolean, and the Boolean values are either true or false. So here we're initializing isSpecial to true and we have an if statement, if (isSpecial), we're going to log out a string. What shows in the console? It's true. So we use true or false to initialize Boolean values. What if we use uppercase True, what's going to show in the console in this case? We get a reference error. True with a capital T is not defined. So remember to use lowercase for true and false. Another way to create a Boolean value is to call the Boolean data types constructor. We'll specify Boolean and in parenthesis we'll pass it Hello. What will show in the console? We'll get true. Hello is a string and it has content, so by passing it to the Boolean function it'll get converted to true, a Boolean value. What about an empty string, is that going to be converted to true or false? What shows in the console? False. And empty string, while it's still a string, has no content. So JavaScript will convert it to false. How about a single space? Is a space considered content? Will this be true or false? What shows in the console? We'll get a true, a space has a very definite ASCII value and that's where we get our true from. How about passing a number to Boolean? Let's pass it a 6. What's going to show in the console? We get true because it's a valid numeric value that's not 0. And passing a 0 into Boolean, what's going to show in the console? We get false. Zero always gets evaluated to false and any other number will be true. What if we convert undefined to Boolean, what's going to show in the console? False. Undefined will be converted to a Boolean of false. How about converting null to a Boolean? What's going to show in the console? We also get false. So with undefined and null represent no real value and they evaluate to a Boolean of false. Let's take a look at this example, here we're setting value to 99.99. What is the type of not not value. Not not is a special way to convert any value or any variable into a Boolean value. The first note will negate it and turn it into Boolean and the second not, or exclamation point, will reverse that. So this has the effect of creating a Boolean value out of any variable. What will show in the console? Boolean. So again, the first exclamation point, not, will convert it into a Boolean value, but it will have the negative value. The second exclamation point, or not symbol, will reverse it, so the typeof not not value is Boolean. So let's say we have a string, no value, and we're setting it to value. What is not not value? What shows in the console? We get true. So the double exclamation point, or two not symbols, have the effect of converting a string, a number, or even a Boolean into a Boolean and you'll see this not symbol twice like this used a lot in JavaScript. It's a very simple way to turn any variable into its Boolean value.
undefined and null
Let's look at the values undefined and null in JavaScript. As a rule of thumb we let JavaScript initialize variables to undefined. If we just put a var variable name, JavaScript will set that to undefined. And we never want to do that explicitly as a developer. If we want to wipe out a variable we use null as a developer, and that's the key difference. If we see that a variable is set to undefined, we'll know that JavaScript did that, and if we see that a variable is set to null we'll know that the source code in some way set that to null. And that's not a hard and fast rule, but it's a general guideline that's used often in many shops. Let's look at some examples. So we have an uninitialized variable, productId. What's going to show in the console? Undefined. The type of productId is undefined and that got set by the JavaScript engine. By not initializing productId it gets set automatically to undefined. And what if we comment out var productId? What is the type of productId? What shows in the console? It's also undefined. Notice we're not getting an error. We're using productId and it hasn't been initialized, but if we run the typeof operator on it, we do get undefined. So what if we initialize productId to null? What is the type of productId? Notice we want the type of it? What shows in the console? Object. We saw this earlier in the course. Null is a special keyword and JavaScript seems to think of it as an empty object. So when we assign null to a variable that variable becomes an object as its data type with no real value. So what is typeof null? What's going to show in the console? It's an object. This is different from undefined. Undefined is a value that we can use, but it's also a data type. Null is considered an empty object by the JavaScript engine. So typeof null is object. How about this example, is undefined equal to null? Notice that we're using two equal signs, not three equal signs for identically equal to. What's going to show in the console? True. JavaScript treats undefined and null as equal. They're types are different, but if we compare them with the two equal sign operator, they are equal. And here we can see it with the identically equal operator, three equal signs. Is undefined equal to null, both in value and type? What shows in the console? False. We know that undefined has a type of undefined and null has a type of object. So they're not identically equal.
Global Scope
Let's start looking at the concept of scope in JavaScript and we'll start off by looking at the global scope. The global scope will hold all the variables that aren't defined within other functions. There's only one global scope. And let's see some examples of it. Here we're creating a new variable called productId and we're initializing it to a string. We're going to log out productId to the console, but we're also going to log out window.productId. Now we're not working in node.js, this course is mainly focused on JavaScript within a web browser, so if you are working in node, instead of window you should use the word global, all lowercase. In a browser, window is the global object, and node, global would be the global object. So this is a bit interesting. We're showing the productId as it is, and then we're showing the productId as it exists in the window global object. What's going to show in the console? We get the productId showing twice, PRD-2000 and PRD-2000. So this example is meant to illustrate that when we start writing JavaScript and we're not in a function, we are working in the global scope. Whether we print out productId without the window object or if we print out the productId on the window object, the global object, we get the same result. And this may seem a bit strange, but the way to look at it is that there's just one global object and it's always available, whether we use the window. notation or not. In the global scope, we also have access to the this keyword and here we're checking if this is identically equal to window. What do you think is going to show in the console? We get a true. So when we're working in JavaScript outside of a function, this is a keyword that is set to the global object, which also can be specified as window. So whether you see this.variable name or window.variable name or just the variable name in the global scope, they're all equal to the same thing. Now we're still working with global scope here, so let's take a look at this code. We're setting description as a new variable equal to hardware product, then we have a function, updateProduct, if this gets called it's going to change description to updated product. Notice that there's no var keyword here in the function. Then we call update product and we'll log out the description. What do you think shows in the console? We get updated product. When our function ran, this description variable still exists in the global scope. This is a very common bug. Most of the time you would want to put a var keyword before it and have it exist within the function only, that would be function scope, which we'll cover shortly, but when we're inside this function, if we don't declare the word description, it will look outside the function in the global scope. So that's why our variable description in the global scope does get updated to updated product. So what about this example? It's similar to before, but we're commenting out the var description in the global scope. We're going to run the function updateProduct, and again, there's no var before the description. What's going to happen in this case? What's going to show in the console? We get updated product. So you can see here that we're not using strict mode. And when we call this function, description is going to be created in the global scope. If we wanted to keep it in the function scope we would need to put a var keyword before it, that way the variable would be local to the function, but when we forget that or if we leave it off on purpose, the value will be created in the global scope. So now we're using strict mode. One of the key aspects of strict mode is to prevent this pollution of the global namespace. There are many, many bugs where values just get dumped into the global namespace where the developer didn't really intend that and by using strict mode we can avoid that. So let's look at this example again, it's the same as the last example, but we're in strict mode now. What's going to show in the console? We'll get a ReferenceError: description is not defined and that occurs when the function executes. Without strict mode, JavaScript will go ahead and create a global variable for us. But in strict mode it won't, it'll throw this reference error. So the rule that I follow is always operate in strict mode, and you'll be able to catch many, many bugs and issues regarding JavaScript creating things for us in the global namespace.
Function Scope
Now let's look at function scope. We saw global scope, which exists outside of the functions, but once we declare a function, it does get its own scope. Also, a function declared within another function also gets its own scope, and let's see some examples of this. Here we have a variable description set in the global scope. When we execute this function, notice the var keyword. Even though this word description is the same identifier as in the global scope, it now exists in the function. So we have description existing in the global scope and we have description existing in the function scope for update product. What's going to show in the console? We get original product. Notice that our console.log actually has nothing to do with the function. It's looking at the variable description in the global scope because console.log is being called in the global scope as well. So that's why executing the function has no effect whatsoever on the global variable. Here we have the function with a variable description set to a string, but we also have a variable updateProductId which is being set to a function, it's a function expression. And the function itself will call its own function, updateProductId, and after the updateProduct function is declared, we'll call it right here. What's going to show in the console? Updated product. So in this example, we can see that when we call console.log description, description does not exist in this function's scope, but it is declared in its parent function, right here. So the way variable lookups work at runtime is it'll look for a description within this function, if it doesn't find it, it'll look in the next higher function and it does find it there. But if it didn't, it would then look in the global scope. Here's another example, now we have description in the global scope, it's set to original product. And we have a similar function to the prior example. We're creating a new variable called description within the function and we have a function expression that's going to get called as well and that's going to access description. So what's going to show in the console? We get updated product. When this function executes it won't find description declared anywhere. So it'll look in the outer function and it will find description defined there and that's what gets printed out. The fact that we have a global variable called description doesn't matter. Description is already found within the containing function. So how about this case, we have a global variable called description, then we have a function called updateProduct, which itself includes updateProductId, another function, which is going to log out the description. In this case what's going to show in the console? We get original product. When our inner most function executes, it doesn't have a declaration for description, so it looks in its parent function. Again, there's no declaration of description there. So at that point it looks out into the global scope and it finds description being set to original product and that's what shows in the console. So here's the same example as the last one except we're commenting out the global variable description. So now description does not exist anywhere, it's not declared in any function and it's not declared in the global scope. What's going to show in the console? We'll get a ReferenceError: description is not defined. When this function executes and it looks for a description, it won't see a declaration. It'll look in the outer function and it will won't find a declaration. Then it will look in the global scope and it's still not going to find a declaration. So we get a reference error. Notice that we're not in strict mode, so whether we're in strict mode or not, we're still going to get this reference error because we're trying to reference it. Again, if we were trying to assign to it and we weren't in strict mode, at that point it would create the variable, but we're not assigning anything to description. We're just trying to reference it to use it, get its value.
Block Scope
Let's take a look at block scope. We've already seen global scope and function scope and those two are the most popular and most used by far. Block scope really isn't used that often and it has to be part of a try-catch statement. Let's take a look at some examples. Here we have a try-catch statement. In the try we're just going to throw an exception, we're going to throw 123, and then we'll catch that and we'll assign the value to e. So what's going to show in the console? We get 123 and that's pretty straightforward. That's how try and catch work, but the interesting thing is that JavaScript normally doesn't have any kind of block scoping, everything gets hoisted to the top of the function or in this case the global area. And if we look at this example, you can see that we're trying to log out the variable e before the try-catch. What do you think is going to show in the console? We get a ReferenceError: e is not defined. So even though it is used in the catch, it doesn't get hoisted. But what if we used the e variable within our try block? We're using it right here, we're going to log out in try and the variable e. Maybe it gets hoisted into the try block, let's see. What shows in the console? No, we still get the ReferenceError: e is not defined. So the only area that e is actually defined is in this catch block here. Now what if we declare a variable within our catch block right here? We're declaring insideCatch and assigning it a string. Then we're going to try to log it out. Do you think that variable will get hoisted? What will show in the console? We get undefined. So when we use variables within our catch block, they will get hoisted. It's only these variables that are passed to catch that have block scope. So it would be just this e right here. And here's an example of how you would see block scoping working in a real application. There would be a try-catch statement. The try block is only going to throw a value and that'll be caught in the catch block and assigned to blockLevelVariable right here. So now blockLevelVariable is in block scope. It's not hoisted out of this statement and it won't exist after the catch block finishes. And just to show that we're going to try to log out blockLevelVar. What shows in the console? ReferenceError, blockLevelVar is not defined. So if it ever ends up that you do need to use block scope in JavaScript, this is how it could be done. You have to specify the single variable or multiple variables in your catch arguments.
Summary
In this module we took a look at hoisting variables. This is not something that's done in other popular programming languages, so it's important to get it right in JavaScript. It is the source of a lot of bugs. We also looked at the primitive types, number, string, and Boolean. We took a closer look at undefined and null and we saw that the JavaScript engine always sets an uninitialized variable to undefined and normally a programmer would set a variable to null. We took a look at variables and functions in the global scope within JavaScript and then we look at function scope and we saw how variables behaved there. Finally, we looked at block scope. Block scope isn't used often, but you will run into it once in a while in JavaScript.
Operators
Introduction
This module is dedicated to operators in JavaScript. JavaScript operators are very similar to the operators found in other programming languages. However, there are a few key difference that you need to know. We're going to start off by looking at the normal operators, addition, subtraction, multiplication, division, and modulus. We'll see how the plus symbol is meant to work with strings as well as numbers and it's quite different than the minus symbol, which is designed only for numbers. And in this module we'll see how conversions take place implicitly. We'll check out JavaScript's unary operators, these are things such as plus or minus in front of a variable or literal and also the not symbol. JavaScript has bitwise operators. Normally the numbers we work with in JavaScript are seen as floating points, but if we start to use bit operators it'll convert the floating point numbers into 32 bit fields to work with and we'll see several examples of that. We'll look at Boolean operators, such as and and or, that are commonly used in conditional statements. And we'll take a look at the equality operators. We have the double equal sign, but we also have the triple equal sign, which is very commonly used in JavaScript. That doesn't only check the value, but it also checks the data type. We'll see several examples of those in action. And finally, we'll check out the relational operators. Those are things such as greater than, less than, greater than, equal to, and so on. So let's start looking at examples with the plus operator.
Addition
Let's look at addition with the plus symbol. Here we have the most simple example, total = 5 + 3. What shows in the console? We get 8. That's just simple addition with numbers. And of course we can also do addition with floating point numbers. What is 5.1 + 3.3? What shows in the console? We actually get 8.399999 and so on. And this is the cause of a lot of bugs in JavaScript. We're working with floating point numbers and they're inaccurate. It seems that the trade off in JavaScript was for speed instead of accuracy. So we get our floating point operations done quickly, but we always have to take into consideration that we might be off by miniscule amounts and this really becomes a problem when we start comparing numbers. If we compared 5.1 + 3.3 to check if it was equal to 8.4, the result would be false, and we'll see that later in the course. But for now just know that floating point calculations are inaccurate, they could be off by miniscule amounts. So the way to fix this is with this example. We're setting total, just as we were before, but total is a number and it has a toFixed function that we can call. Notice that we're passing the number 2 to toFixed, that means it'll round to 2 decimal places. What shows in the console? 8.40. So remember when you're doing calculations with floating point numbers, in this case addition, you probably want to call the toFixed function on that number in order to round it. Here we have an example where we're adding strings, PRD + X99. What shows in the console? We get PRDX99, so that works as you would expect. It just concatenates the strings. How about this one where we're adding a string, PRD + a number, what's going to show in the console? We get PRD2000. So it converted the number 2000 into a string. It didn't try to convert PRD the string into a number. And that's the case with the plus statement in JavaScript. It's usually going to try to evaluate into a string if possible. And if we reverse the order, 2000 + PRD, what shows in the console? In that case it also converts 2000 into a string, even though it was listed first. So how about this case, we have 2000 as a string plus 500 as a string? What shows in the console? We get 2000500. So there's no implicit conversion into numbers. Once JavaScript sees the strings, it just concatenates them, even though they're both valid numbers. How about this one, we have 2000 as a number plus 500 as a string. What shows in the console? Again, there's no implicit conversion into a number. It's going to convert everything into a string. So we get 2000500 as a string, we don't get 2500. So what is a number, in this case 2000, plus undefined? What shows in the console? Not a number. Remember that when we're working with numbers and we have an expression that JavaScript sees as numeric, it's not going to throw an error if we work with things such as undefined. It's going to be unable to perform the calculation. So we get not a number. How about this one, we have a string, PRD, plus undefined. What shows in the console? We get the long string, PRDundefined. JavaScript sees the string PRD, so it's going to expect undefined to be a string and its value is the string undefined. And this is different from the previous example in that before we were working with a numeric type, in this case we're working with the string PRD. How about this one, what is 2000 plus null? What shows in the console? We get 2000. In a number context null is going to be treated as a 0. How about PRD as a string plus null? What shows in the console? We get PRDnull. Again we're not working with numbers here. JavaScript sees the string and it sees the plus sign and it's going to try to concatenate null to PRD. So we get PRDnull. How about 2000 + not a number? What shows in the console? not a number. JavaScript has no idea how to do this calculation so it leaves it as not a number. Now what about a string plus not a number, what shows in the console? We get PRDNaN. So it just takes the string representation of not a number and appends it or concatenates it to PRD.
Subtraction
So now let's look at subtraction with the minus symbol. This is different from addition in that, well obviously it's subtraction, but also JavaScript is going to treat the context more as a numeric context. You can't really subtract strings from each other, but you can subtract numbers and that's what JavaScript is going to be looking for. So let's see the examples. What is 30 - 20? What shows in the console? 10, that's very straightforward. Here we have 3.8 - 2.1. What shows in the console? 1.6999999 and so on, but it ends in a 7. So again, we're off by a miniscule amount and we'll see later in the course how this is a major problem, but we can always round the number in order to get computations and especially conditional statements to work properly. Here we're performing 3.8 - 2.1, but we're calling total.toFixed, and we're passing toFixed(3), so we want to round it to 3 decimal places. What shows in the console? 1.700. So now that it's rounded, we're not going to run into any strange comparison bugs. So what happens if we have 2 strings, 300 as a string minus 200 as a string? What shows in the console? We get 100. JavaScript sees the minus sign and it immediately puts everything into a numeric context. So it will implicitly convert the 300 into a number and the 200 string into a number as well. How about this one? We have a string that's not necessarily numeric minus another string that's not necessarily numeric. What shows in the console? Not a number. When working in JavaScript you have to get used to calculations resulting in not a number. You're not going to get a syntax error and you're not going to get an error thrown, you're just going to get a result of not a number. What about this one, 300 - undefined? What shows in the console? Not a number. How about this one, 300 - null, what's going to show in the console? We get 300. While undefined results in not a number, null in a numeric context is treated as 0. Here we have an object and we'll cover objects later in the course. It has a property called valueOf, which is set to a function which returns 100. Then we're setting total equal to 300 minus the object. What's going to show in the console? We get 200. When we use an object in a numeric context, JavaScript is going to look for that valueOf property. So if you do have some kind of specialized object that needs to operate as a number, this is how you would do it. You just create your function and assign it to the value of property. So essentially 300 - valueOf, which is 100 = 200, our answer. What si 300 - not a number? What shows in the console? Not a number. Any mathematical operation with not a number results in not a number. How about this, 300 minus an empty string. What shows in the console? We get 300. The empty string is converted into a 0.
Multiplication, Division, Modulus
Let's look at operators for multiplication, division, and modulus. Let's start off with multiplication, which uses the asterisk symbol like other programming languages. What is 9 times 3? What shows in the console? 27. So that's straightforward multiplication with numeric values. How about this one? 1.1 times 1.1. Now 11 times 11 is 121, so theoretically the answer should be 1.21. What shows in the console? Yes, we get another problem with floating point numbers. We get 1.21, a string of 0's, and a 2 at the very end. So be sure when you're doing comparisons to use the toFixed function on the number. And here we can see an example of that floating point rounding problem that I've been talking about. We'll calculate total 1.1 times 1.1 and log it out. But if the total is not equal to 1.21, we'll also show the string Big Problem. What do you think is going to show in the console? Well first we get our number with the floating point error in it, and then we get Big Problem. So we know mathematically that total is equal to 1.21, but JavaScript doesn't see it that way. That's why we always need to round our numbers before doing a comparison. And here we'll do the comparison. The top part of this example is the same, but now we're going to compare total.toFixed rounded to 2 decimal places, we're going to compare that to 1.21. What shows in the console? We get our number with the floating point error in it, but then we get fixed. This time our comparison did work as planned because we used toFixed to round it. What is 20 times not a number? What shows in the console? Not a number. Again, you've always got to be aware of that if you're working with something that's not a number, the result is going to be not a number. What is 20 times undefined? What shows in the console? Not a number. What is 20 times null? What shows in the console? We get 0. Again, in a numeric context, null is treated as a 0. Unlike undefined, which will result in not a number. How about this one? We have an object with a valueOf property and we want to calculate four times that object. What shows in the console? We get 400. Again, when we treat an object in a numeric context, JavaScript will look up the valueOf property to find out which number should be used. What is 4 times infinity? What shows in the console? We get infinity. What is -4 times infinity? What shows in the console? We get negative infinity. Working with infinity can be confusing at times and a lot of developers avoid it, but in these two cases it was pretty straightforward. We'll get positive infinity or negative infinity, depending upon what we're multiplying it by. How about this one, numeric 4 times the string XYZ? What shows in the console? So the whole expression fails numerically and we get not a number. How about this one? What is 9 divided by 0? Now we're getting into division. Most languages would throw an exception, some kind of divide by 0 error. But what shows in the console? We get infinity. My guess would have been not a number because division by 0 by nature is undefined, but I could see how it could result in infinity. The important thing to note is that an exception was not thrown. In JavaScript it's important to check out your numbers for not a number or some version of infinity, whether positive infinity or negative infinity. And how about this one, -9 divided by 0. What shows in the console? Negative infinity, and that makes sense given the previous problem. What is 9 divided by 3, but the 3 is treated as a string in quotes. What shows in the console? We get 3. So for operations like multiplication, division, and modulus, JavaScript is going to implicitly convert strings into numbers where it can, 9 divided by 3 is 3, the answer. How about 9 modulus 4? Remember modulus means the remainder. What shows in the console? 1. 9 divided by 4 is 2 with a remainder of 1, so we get 1 as the answer. And modulus works a lot like the other operators in this video, so we're not going to go through all those examples. But how about this one, what if there's a bunch of white space around the 4? What's 9 divided by a string with the number 4 but it's surrounded by white space? What shows in the console? 1. So when JavaScript does try to implicitly convert the string, it will get rid of white space.
Unary Operators
Let's take a look at some unary operators in JavaScript. We have things such as the increment ++ operator, the decrement operator --, plus we can put a positive for a negative symbol in front of a value. Here we're setting level to 5 and we're calling ++level, what shows in the console? We get 6. This is the straightforward increment operator that we see in many other languages. We can also put the ++ after the value. What shows in the console? We also get 6. How about this one, we're setting level to 5 and then we're setting nextLevel to ++level. What's going to show in the console? As expected we get a 6. So this is the same as the last example except we're doing a post increment, we're putting the ++ symbol after level. What's going to show in the console? We get 5. Next level is assigned to level, which is 5, and after that assignment takes place, then level gets incremented. So at this point level is actually equal to 6, but nextLevel is still 5. We also have the decrement operator. Here we're setting nextLevel to --level. What shows in the console? We get a 4, 5 - 1 is 4 and that's what we get from the --level. How about this one? We're setting level and base and then we're setting nextLevel equal to level-- times base. What shows in the console? We get 50. Remember that when we do the post decrement, level--, that decrement won't take place until after that line is complete. So we get essentially 5 times 10, 50. And how about this one, this time we're using --level instead of level--. What's going to show in the console? We get 40. So level is decremented from 5 to 4 and then it's multiplied by base, so we get 40. How about the case where we forget to initialize a variable or a variable somehow gets set to undefined as in this case? What if we try to increment it? What's going to show in the console? Not a number. So we're using undefined in a numeric context, we get not a number. What if level is null and we try to increment null? What's going to show in the console? We get 1 because when null is used in a numeric context, it's going to be treated as 0, so it gets incremented to 1. In this example let's look at the + operator, but it's used as a unary operator. Here we're setting value to 9 and then we're setting value equal to +value. What shows in the console? We get 9. And as we'll see, the + symbol really doesn't do anything, it just leaves the value as is. How about this case where value equals -9 and then we set value equal to +value. What shows in the console? We get -9. So again, the + symbol does nothing, it leaves the value as it is. You might think it would convert it into positive 9, but it doesn't. If you wanted to flip the sign on a number, you would use the negative symbol. Here we're setting value to a string called calc and then we're setting value equal to +value, so here we're accidentally using a string where we probably meant to use a number. But what's going to show in the console? We get not a number, even though we're using a string, it's used in a numeric context again. So we get not a number when JavaScript tries to parse calc. Now let's take a look at the negative symbol, value = 42 and then value is being set to -value. What's going to show in the console? We get -42. So if we wanted to flip the sign, we use the negative symbol. And again, the positive symbol doesn't do anything. Here we have value = -42 and we're setting value equal to -value. What's going to show in the console? We get positive 42. Again we use the negative sign to flip the sign. And if we set value to a string, which is probably an accident in our code, what happens if we try to negate a string? What shows in the console? Not a number, and that's similar to the way the plus symbol worked on a non-numeric value.
Bitwise Operators
Let's take a look at the bitwise operators in JavaScript. You're not going to run into these too often, but they are out there and you could have a need for them. In these examples, we're going to make heavy use of the parseInt function. So the first argument we're passing 1010 and that's a binary number. The second argument is 2 and that's how parseInt knows that it's a binary number. And on the second line, we're setting num2 to something similar, the binary value is 0110. And on the third line, here is our binary operator, the ampersand, the & symbol. We want to and these two binary numbers together, so in the case where we have a value 1 and 1 in each binary number, the result should get set to 1 as well. So what's going to show in the console here? We get 10. This 1 and 1 is going to stay 1 in the result and we just drop down the 0 as well. Remember we're working with binary numbers and it's the bits that are important. So the actual decimal value doesn't matter, we're just looking at bits right now. Here's a bitwise or symbol. This example is very similar to the first one except we're using or now. So if the bits in num1 or the bits in num2 line up and one of those is set to 1, we'll get that in the result. So what do you think is going to show in the console? We get 1110. In our four digit binary number, it's only the last digit that doesn't contain a 1. And here we can see the exclusive or symbol, so when we exclusive or to binary numbers, one has to be 1 and one has to be 0 for the 1 to come down. So what's going to show in the console? We get 1100. The 1 and 1 here are not exclusive, so they evaluate to 0. We can also manipulate the bits of a binary number with the left and right shift operators. Here we can see a left shift operator, so our binary number is 0001 and we're going to shift it to the left 2 places. What's going to show in the console? We get 100. So we take our 1 digit shift it to the left 2 spaces and we get 100. How about this one, this time we're shifting the bits to the right three place values. So we're working with 1000. What's going to show up in the console? We get 1. The 1 shifted over 3 places and we're left with 1. So here we have an example of a negative binary value, and we're not going to go into detail on negative binary values. It gets complicated because we're working with 2's compliment numbers and there's just a lot of rules and a lot of confusing aspects to it in JavaScript. It's not a feature that's used a lot. But just to show you one of the things you'll run into if you do work with negative binary numbers, let's take a look at this example. So we have the number 1000 as binary, but we're making it negative. Then we want to shift it to the right 3 places. What do you think is going to show in the console? We get -1 and that's pretty simple and straightforward, but we have another operator, which is a triple shift right and triple shift left; let's take a look at that. We're going to take the positive value, 1000, and shift it to the right 1 space. The triple shift will carry over the sign. So the sign for positive is 0 and the sign for negative is 1 in the most significant bit. So what's going to show in the console? We get 100, which is straightforward. But what if we're working with a negative number? We have -parseInt 1000 and we're shifting it to the right 1 bit, what's going to show in the console? Well we get our 100, but the rest of the binary digit was filled in with 1's because it's a negative value. So if you are working with negative binary values, make sure you understand 2's compliment notation and be aware that the negative sign carries over in a lot of these operations.
Boolean Operators
Let's take a look at the Boolean operators in JavaScript. Boolean operators work with true and false values. Here we're setting the variable value to not true. The not symbol is a Boolean operator. What's going to show in the console? False. And that's pretty straightforward. Also we can say not false, what's that going to show? True. But what about not 99? What's going to show in the console here? We get false. A numeric value is always going to evaluate to true unless it's 0. So 99 evaluates to true and we're not saying not true, which becomes false. How about not 0? What's going to show in the console? We get true. 0 evaluates to false and not false is true. Now what if we're working with an empty string? We have our quotes, but there's not even a space between them. What's going to show in the console? True. An empty space evaluates to false. How about not A, we have a string of A, what's going to show in the console? False. If we have anything in our string it's going to evaluate to true and not true is false. How about this one, not space? We only have one space character in our string, what's going to show in the console? False. Even a space within a string evaluates to true. We'll cover objects later in the course, but here we're creating a new one. We're calling new Object, but we're putting the Boolean operator not in front of it. What's going to show in the console? False. New Object will return a simple valid object and an object would be true, not true is false. How about this one, not null? What's going to show in the console? We get true. Null evaluates to false, so we flip it over to true. How about not undefined? What's going to show in the console? We get true. Undefined evaluates to false and we flip that over to true. What about not a number? What's going to show in the console? We get true. Not a number evaluates to false, so the Boolean not symbol converts that to true. Here's something that we see a lot in JavaScript, two not symbols together. The first not symbol converts it to a Boolean and negates it. The second not symbol un-negates it. So this is a simple way to turn any value into its Boolean value. So when you see the bang bang or the two exclamation points, just know that the value that follows it is being converted into a Boolean value. So what's going to show in the console? False. And here we have the double ampersand operator. What does true and true evaluate to? What's going to show in the console? We get true. How about this one, true and false? What's going to show in the console? We get false. We need both of the conditions to evaluate to true in order to get an answer of true. How about this one, false and true? What's going to show in the console? It's also false. And how about false and false? What's going to show in the console? That also evaluates to false. So the double ampersand, to evaluate to true, both the conditions need to evaluate to true. Here we have a pattern that we see in JavaScript once in a while and this is very different than other programming languages. Let's say we have an object, it doesn't really matter what the properties are, but we want to evaluate object and 99. What's shows in the console? Well we get 99 and that's very confusing. Normally the double ampersand operator is going to result in a true or a false, but when we're working with JavaScript if the first operand is an object, the second operand is always going to be returned, and yes that is an arbitrary rule, but you'll see why it has a use coming up. So object and any value is going to result in that value being returned, the second operand. So what if we have an object and 0? What's going to show in the console? We get the 0. Normally a 0 evaluates to false, but you have to remember this special condition. If the first operand is an object, the second operand is always going to be returned, so we get 0 as the answer. How about this one, we're setting value to object and object. What's going to show in the console? We get the object back. Again if the first operand is a valid object, no matter what the second operand is it gets returned, and that's what we get. Here we're setting value to true and object. What's going to show in the console? We get our object. If the first operand evaluates as a Boolean to true, it's going to return the second operand, in this case our object. And what about this one, we're setting value to null and 99. What's going to show in the console? We get null. If either one of the operands is null, null gets returned. Here's an example where we have a string as the first operand and null as the second operand. What's going to show in the console? Again we get null. If either operand is null, that's going to be our result. What happens if we're working with a string and undefined? What's going to show in the console? We get undefined. If either operand is undefined, that's what gets returned, undefined. What about a valid string and not a number? What's going to show in the console? We get not a number. Again, if either operand is not a number, whether it's the first or the second, Not a number is going to be returned. So what about this one? We haven't defined productId, we're not in strict mode, but we're going to be using productId. What's going to show in the console? We get false. Now if you thought we would get an error, normally you would, but the JavaScript runtime engine notices that the first operand is false, so it just completely ignores the second operand. It knows the result is going to be false. So now we're setting a productId to 5 and we're setting value equal to false && and we're going to increment productId. Now this is confusing code and you probably would never write code like this, but you could run into it. Do you think the incrementation is going to take place or not? What's going to show in the console when we print out productId? We get 5. So remember, when we're evaluating the double ampersand and operator, the second operand isn't always going to be looked at. In this case, we know that the expression is going to evaluate to false. So the second operand is completely ignored and the incrementation doesn't even take place. Here we have the Boolean or operator. If either operand is true we'll get a true. So what's going to show in the console? We get true. How about this one, value equals true or false. What's going to show in the console? We get true, just one of the values needs to be true to get a true result. How about this one, value equals false or true, what's going to show in the console? We get true because the second operand is true. How about value equals false or false? What's going to show in the console? We get false. So now we're back to working with objects with the logical OR and, again, just like the logical and, things are a little bit strange in JavaScript. It doesn't always work the way you would expect. So here we're setting value equal to a valid object or 99. What do you think is going to show in the console? We get our object, and the rule in JavaScript is that if the first operand is an object, that objects gets returned. So the 99 is completely ignored. How about this one? We're setting value equal to false or 99. We're not using that object at all. What's going to show in the console? We get 99. The first operand evaluated to false so whatever the second operand is, it's going to get returned. And here we have a somewhat realistic example and hopefully this will explain some of this weird behavior with the Boolean and and the Boolean or operators. Let's say we have an object called defaultSettings and we set a field called who to default. We have another object called userSettings and we set the field who to user. And this line is something you're going to run into a lot. We're setting value to the user settings, but what if the user didn't specify any settings? We need it to revert to the default settings and this is how we do it in JavaScript. We set value equal to userSettings or defaultSettings. So if userSettings is a valid object, we're going to return it, but if it's not a valid object, we're going to return the second operand, defaultSettings. So in this case, what's going to show in the console? We get the object where who is set to user. That's our userSettings. So in this case there are valid user settings and that's what gets returned. Let's look at another similar example. We're setting our defaultSettings. We're setting who to default, but we're not setting the userSettings. We're just leaving them undefined as set by the JavaScript engine. We're setting value equal to userSettings or default settings. What's going to show in the console? We get our default settings. We get the object where who is set to default. And hopefully that adds some sense to these operators. If the user settings are not defined, we always want to return the second operand, the defaultSettings, and you'll see this type of code all over the place in JavaScript, especially if you look into some of the libraries, like jQuery or a framework such as Angular. It's a very common pattern.
Equality Operators
Let's look at the equality operators in JavaScript. There's actually a little bit more in JavaScript. We have the normal equal to and not equal to equality operators, but we also have identically equal to and not identically equal to operators. And we'll see the difference in this video. In these examples, mainly we're going to be looking at the conditional of an if statement. We're going to log out true or false, just to make things simple. But here we're comparing true with 1, what's going to show in the console? We get true, but it's important to understand why we get true. It's not as simple as you might think. Let's look at the next example. Here we're comparing true with the number 2. What's going to show in the console? In this case we get false. So you would think that the value 2 would be converted over into Boolean true and would get a true answer, but we don't. The opposite happens. True gets converted over to a number, and that's not really obvious in JavaScript, and it is the source of some bugs. True will get converted over into the number 1 and false will get converted over into the number 0. So comparing 1 with 2, we get false. In the previous example we compared true with 1 and we got true. How about this one, we're comparing false with 0. What's going to show in the console? We get true. What if we compare a numeric value 42 with a string value 42? What's going to show in the console? We get true, but what happened? Did the numeric 42 get converted into a string or did the string value 42 get converted into a number? Well like we saw with the Boolean, the context of this conditional tends to be numeric. In JavaScript the string 42 is going to be parsed and an attempt is going to be made to convert it into a number and that's what happens, that's why we get true. Here we have an example of an object. It's a simple object with one property, a function called valueOf, which returns 42. So what happens when we compare the literal number 42 with this object? What's going to show in the console? We get true, and the reason why is right here. If we're using an object in a numeric content, such as this conditional, the JavaScript engine is going to look for the valueOf function within the object and here we can see it returning the number 42, thus we get true. What about this example, we have an object, but we don't have the valueOf function anymore. But we do have a custom toString function, that's going to return 42. So what happens when we compare 42 with the object? What's going to show in the console? We get true. And the reason why is the JavaScript engine in a numeric context, the first thing it's going to look for is valueOf, if it fails to find the valueOf function within the object it's going to look at the toString function and there's where we get our 42, thus the answer is true. How about this one, we have an object and the name field is set to trigger, and we have a second object, object 2, which has the same exact property, name is set to Trigger. What happens if we compare these two objects? What's going to show in the console? We get false. Each object has its own individual memory space despite having the same exact properties. How about this one, we have a single object with a single property and we compare the object to itself. What's going to show in the console? We get true, the two pointers to object are the same. So let's combine those last two examples, let's say we have an object with a name field of trigger and we set object 2 equal to object. What happens if we do the comparison now? What's going to show in the console? We get true. We copy the object pointer from object to object 2, so they point to the same memory location, storing that object, thus we get true. And we'll cover objects in more detail later in the course, but for completeness I'm adding it here. So what about this scenario, what if for some reason we're comparing null with undefined? What's going to show in the console? We get true. Now there's no real conversion taking place here, this is just a rule within JavaScript. Null is equal to undefined when we're doing a comparison. How about this one, we're comparing undefined to 0. What's going to show in the console? We get false. When we compare undefined to any value we're always going to get false, except for that special rule we just saw of comparing it to null, in that case it would be true. How about this example, we're comparing null to 0. What's going to show in the console? We get false. In a numeric expression, null is usually going to be converted to 0, but this is a special case where we're doing a comparison and the rule in JavaScript with comparisons is you can't compare null to anything, it's going to result in a false expression. And of course, we have the other rule that we talked about where null happens to be equal to undefined as a rule. How about this one, is not a number equal to not a number? What's going to show in the console? We get false. Not a number, if you remember, is actually a number, it has the number data type. So we're working in a numeric context here and by rule, not a number is not equal to not a number. So we've been looking at the equal to comparison symbol, but now we're going to use the not equal to. We won't go through the whole range of examples that we just saw, but let's take a look at a few examples. Is numeric 42 not equal to a string forty-two? What's going to show in the console? We get true. The JavaScript engine is going to try to parse the string forty-two, and it's not smart enough to convert that, so since we're doing a not equal symbol, the answer is true. How about this one, is 55 identically equal to the string 55? Now this is the first time we're seeing that triple equal sign. Triple equal sign means the value is the same and the type is the same. So what's going to show in the console? We get false. The type is different. We're comparing a number to a string, so we get false, as long as we're using that is identical to operator. So about this one, 55 is identically equal to 55? True or false? What's going to show in the console? We get true. Can we compare the Boolean value false, is that identically equal to 0? What's going to show in the console? We get false. Again, with the triple equal sign, it's going to compare the types and a Boolean type does not match up with a numeric type. Is null identically equal to undefined? Well we saw earlier that null is equal to undefined if we use the double equal to operator, but with the triple equal to operator, what do you think is going to show up in the console? We get false. Null and undefined are very different types and the rule only holds that they are equal with the double equal symbol, not the triple equals. And how about this one, we're comparing 55 with the not identically equal to symbol with another numeric 55. What's going to show in the console? False. They are identically equal, they're both numbers and they both have the value 55. So we're not going to go through a whole bunch of examples with the not identically equal sign, it's just the opposite of the is identically equal sign.
Relational Operators
Let's quickly look at the relational operators in JavaScript. These are very much the same as they are in other programming languages. So let's just quickly go through some examples. Is 55 less than 66? Are we going to get a true or false? We get true. And we also have the less sign or equal to symbol, is 55 less than or equal to 55? What's going to show in the console? We get true. And we have the greater than symbol, is 55 greater than 55? What's going to show in the console? We get false. They are equal. The first operand is not greater than 55. How about 55 is greater than or equal to 55? What's going to show in the console? True. And this is all pretty straightforward if you've worked in any programming language, this should be familiar. What if we compare strings in JavaScript? Alpha is less than beta. What's going to show in the console? We get true. Alphabetically, alpha is less than beta. Notice that they're both lowercase, we'll see soon that there's a problem comparing uppercase and lowercase. How about this one, we're comparing alpha with alph. Is alpha less than alph? What's going to show in the console? False. Because alpha has an extra character, the a at the end, it's actually going to come after alph. Now how about this one, we're comparing beta with a lowercase b, is that less than Alpha? And Alpha has an uppercase A. What's going to show in the console? False. So we know beta will come after Alpha. But what about this one, is Beta with an uppercase B, is that less than alpha with a lowercase a? What's going to show in the console? True. So in this case b comes before a, but what you need to remember is that we're comparing the ASCII values or the Unicode values and all of the uppercase ASCII values come before the lowercase values. And it's something to always be aware of when you're doing string comparisons and case is an issue. The uppercase characters do come before the lowercase characters, so we get true as an answer here. So here's one way to solve the problem, we can say if Beta.toLowerCase, which will convert it all to lowercase, if that's less than alpha.toLowerCase, we can do the comparison that way. What's going to show in the console? We get false. By converting everything to lowercase we can get a more sane comparison. How about this one, we're comparing a string 42, is that less than 55? What's going to show in the console? The answer is true. Remember during a comparison the JavaScript engine in most cases is going to try to work in a numeric context, so the JavaScript engine will try to convert the string 42 into a number, thus the answer is true. Now how about this one, we're comparing a string 42, is that less than a string 142? Now we know numerically that that would be true, but now we're working with strings and both the first and second operand are both strings. So there's not going to be a numeric conversion. What's going to show in the console? False. And the reason why is it's going to compare the strings as strings and 1 comes before 4, thus the answer is false. Now let's take an example that could be the source of a bug. We're setting total to not a number. Normally that would happen as an accident or possibly as some form of logic that goes bad in your code. But one way or another total is getting set to not a number. Now if total is less than 5, we want to log that out to the console and if total is greater or equal to 5, we want to log that out to the console. So what's going to show in the console in this case? Remember total is not a number. We actually don't get anything in the console. You would think that by comparing total to less than 5 and greater than or equal to 5, one of those would be true. You always have to be careful in the case that a value is equal to not a number, in that case, neither of these comparisons is going to result in true.
Miscellaneous Operators
For completeness sake, let's take a look at some miscellaneous operators. Here we have what's called a compound assignment operator. We're setting total to 6 and then we're saying total += 4 and what that means is simply we're adding 4 to total. Another way you could write it is total = total + 4. So what do you think is going to show in the console? We get 10. In these compound assignment operators, you can use pretty much any operation. Let's see another example. We're setting total to 6 and then we set total -= 4. Again we have a compound assignment operator, -=. What's going to show in the console? We get 2. Essentially this line means total = total - 4. We can also do multiplication with an equal sign. What's going to show in the console? 24. This line essentially means total = total times 4. And here's a case with the division symbol and an equal sign. What's going to show in the console? We get 2. Six divided by 3 is 2. And we can also use the modulus operator with the equal sign as a compound assignment operator. What's going to show in the console? We get 2. If we take the remainder of 6 divided 4, we get 2. You might also see the shift operator with an equal sign. Remember the shift operator is going to shift the bits to the left or essentially multiply it by 2 for each shift. So we're going to shift it twice for the number 2 here, so what's going to show in the console? We get 4. We take the number 1, we multiply it by 2, and then we multiply it by 2 again, we get 4. Now we can go the other direction as well, it's essentially saying total = total shifted to the right 1 bit. Which is the same as dividing by 2. So what's going to show in the console? We get 2. Four divided by 2 is 2. Now here's a tricky one, we're setting total to 6 and we're saying total *= 4 + 1. So which operator has precedence here? Is it the *= or is it the +? And that's where precedence chart comes in extremely useful. Let's look at one online. So I'm here on Mozilla's developer network and we're looking at operator precedence. There's a long URL up here, but the best way to find it is really to go to Google and search on operator precedence JavaScript and this should be the first search result. And here we can see a list of all the operators and which ones precede which other operators. Here's the table here and let's quickly look back at our example again. We need to compare the *= with the + operator, which one has precedence? So I'm going to scroll this down and we'll get to the table and I'm going to zoom it in a little bit so we can see the operators better. So here we have the individual operators and the precedence value. Depending on the precedence value, if it's a higher value it's going to occur first. As we can see here, the highest precedence is grouping and obviously anything in parenthesis always comes first. And then as we drop down in precedence, things just come later in the evaluation cycle. So let's find our *= operator, it's right here. It's at precedence level 3. And let's find our + operator. Plus is way up here at precedence level 13. So the addition is going to occur first and then the assignment is going to happen. And again, understanding operator precedence is vitally important. It's the source of a lot of bugs when one developer thinks something takes precedence when it doesn't, and a lot of times you're actually going to see a lot of people using the parenthesis right here, because that makes everything clear. Most developers know that if you use parenthesis, that's the highest level of precedence, it'll always occur first, and just to make sure again, our addition is at precedence level 13, and *= is at precedence level 3. So given that, what's going to show in the console? We get 30. Four + 1 is going to occur first. So the line essentially says, total is equal to total, which is 6, times 5. So the answer is 30. Now another simple operator we have in JavaScript is a comma. When we declare variables we can actually specify a comma as we initialize new variable names. So here we see var total = 99, tax = 9. What's going to show in the console? We 99 and 9, just as expect. Another operator that's a bit confusing, but you'll see it once in a while is the comma operator used with numbers or other values within parenthesis. Now this has nothing to do with arrays, so we're setting total equal to 99, 88, and 44. What's going to show in the console? Remember it's not an array. We get 44. When we list out values like this within parenthesis, the last value is the value that's taken. And my suggest is don't use this. A lot of developers won't understand it and it may not work cross browsers.
Summary
In this module we looked at the basic arithmetic operators, addition, subtraction, multiplication, division, and modulus. We looked at unary operators, mainly plus and minus. We looked at bitwise operators where JavaScript actually converts a floating point number into 32 bits for us as an integer in order for us to work with it. And again, this isn't really common in JavaScript, but it does have its uses. We looked at the Boolean operators, mainly and, or, exclusive or. And we looked at the equality operators. In JavaScript it's similar to other languages, but we do have the is identically equal to and is not identically equal to operators, which are three equal signs and not three equal signs respectively. We looked at the relational operators, which are very similar to other languages. And we looked at some miscellaneous operators, such as the comma symbol and the compound assignment operators.
Arrays and Reference Types
Introduction
Welcome to this module titled Arrays and Reference Types. In JavaScript there's a big distinction made between primitive types, things such as numbers, Boolean values, and strings, and reference types. Reference types include things like arrays and objects, those are the most popular ones. And in this module we'll be looking at this distinction and going over most of the reference types. We're going to start by getting a good explanation of what reference types really are and how they work with the JavaScript runtime engine. Next we'll take a look at a bunch of examples which show reference types being used in real situations. Next, we'll take one of the popular reference types, which is arrays, and we'll look at that in detail. We'll take a look at dates, which is another type of reference type, and we'll look at regular expressions. Now probably the most popular form of reference type is actually an object, and we'll dedicate a whole module on objects later in the course. So we'll just look at those briefly in this module. But let's get started and review what reference types really are.
Understanding Reference Types
We really need to understand what reference types are and how they differ from the primitive types in JavaScript. First off, let's take a look at primitive type storage. He we have a variable n being initialized to the number 42. So it's a numeric primitive type. What the runtime engine is going to do is it's going to allocate a bit of memory and it's going to refer to this memory location as n, the variable name. And inside that memory we're going to get the number 42. Here we have a string, a variable s being initialized to the words forty-two. Again, JavaScript is going to create some internal memory, it's going to call it s, and it's going to store the value 42 as a string. And another primitive type is a Boolean value. So here we're setting a var b equal to true. The runtime engine will create that variable b, assign it some storage, and insert the value true there. So this is very straightforward. And this is how primitive type storage works. Now let's take a look at how assignments work with primitive type storage. We'll take a variable n and initialize it to 42 and then we'll take a variable a, but we're going to assign n to it, so the JavaScript engine is still going to create an area in memory called a and it's going to copy the value from n. So that 42 from n will get copied into a different memory location, a. And it's to know that these are two distinct memory locations, n and a, and the value is stored twice. So now what happens if we assign the number 9 to variable a? Well a is going to get wiped out and the value 9 will be stored there. And notice n, n is still set to 42. N doesn't change at all. So in primitive type storage, values get copied around a lot, and that's very different from how reference types work. Let's take a look at reference type storage. We'll create a variable called o and set it to an object. The object has a simple property called name set to Jill. JavaScript is going to create a memory location for o, but it's not going to place the object there, it's going to place a pointer and we never have access to that pointer as a developer. We don't know where it points, but we know it points to some unknown memory location and that's where the object gets stored, and this is why an object or an array or a date, a regular expression, or any one of those reference types are called reference types. It contains a reference or a pointer to the information. Now let's create a new variable named o2 and we'll assign o to that. What's the runtime engine going to do? Well it's going to create a memory location for o2 and then it's going to copy the pointer down from o. So it's not copying the object, it's just copying a pointer to the object. And again, that pointer points back to the same memory location as o. So o and o2 are both pointers pointing to the same memory location and these are reference types. They reference the same object. So now what happens if we set o2.name equal to Jack? Well the name of Jill is going to get wiped out and it's going to be replaced with name of Jack. But now you'll notice that not only does o2.name equal Jack, but o.name is also equal to Jack. And if this is your first time working with reference types, this is a big problem for a lot of developers. You really need to understand the mechanics of this in order to work with reference types in JavaScript, which you're surely going to do. By changing o2.name, we're also changing o.name because both those pointers point to the same memory location by reference. Let's look at some of the common reference types we're going to be using in JavaScript. Objects are probably the most popular and they'll get a module all to their own in this course. We have arrays and we're going to look at arrays in this module in detail. Dates are a common reference type. Regular expressions are common reference types. And functions are also reference types. We'll cover functions in a lot more detail later in the course as well. We can also use some primitive values as reference types if we use JavaScript's built in wrappers for them. And we'll take a look at those later in the course as well. But mainly when we talk about reference types, most of the time we're going to be working with things like objects or arrays.
Reference Type Examples
Let's look at some source code examples of reference types in action. Here we have a new object called blog and the name is set to Ski Utah. Then we'll create a variable called updated blog and assign blog to that. Then we're going to log out updatedBlog.name. What's going to show in the console? We get Ski Utah. So updated blog and blog are going to point to the same object in memory. In this example we also are setting up blog and we're setting updated blog equal to blog, but we're going to change blog.name. We're changing the name to Rocky Mountain Skiing. So what happens when we log out updatedBlog.name? What's going to show in the console? We get Rocky Mountain Skiing. Because objects are reference types, updatedBlog and blog are going to point to the same memory location. So updating blog has the same effect as updating updatedBlog. Likewise, in a similar example, what happens if we update the updatedBlog.name and we print out the blog.name? What's going to show in the console? We get Rocky Mountain Skiing. So just because we took blog and assigned it to updated blog doesn't mean we clone the object, we just copied a pointer to the object in memory. So updating the updatedBlog.name will also update blog.name. And a lot of times you're going to see these modifications taking place within a function. So here we have our blog variable and we also have a function called changeBlogName and we're just going to set the name to no name within the function. So we pass blog into the function and what's going to be the result? What's going to show in the console when we print out blog.name? We get no name. So when we pass a reference type to a function, it's the same thing as passing a pointer to it. And even though it's called localBlog with the function, it will still modify the object. So it's always important to know what exactly are we passing to a function. If it's a reference type it could get modified and we may or may not want that. So it's just important to be aware of that. Functions can modify reference types. We'll cover arrays in more detail soon, but here we have a simple array set to the values 1, 2, and 3. And we're assigning that to a1, and then we're assigning a1 to a new variable, a2. We'll set a1 subscript 0 to 99. And then we're going to log out a2 subscript 0. What's going to show in the console? We get 99. Arrays are definitely reference types. When we copy a1 over to a2 right here, we're just copying a pointer to the array values. So modifying a1 has the same result as modifying a2 and the answer is 99.
Array Fundamentals
In this video we're going to take a look at array fundamentals. Arrays have some unique qualities in JavaScript, and we'll take a look at those in detail. Here's a common way to initialize an array, we'll create a new variable called entries and we'll use the new operator with the Array object and we'll initialize the values of the array to Trains, Plains, and Automobiles. And just to start out, let's log out entries instanceof Array, this will be true or false if entries is actually an array. So what shows in the console? We get true. This is a very valid way of creating an array and we use the instanceof operator to confirm that it actually is an array. One of the unique things about JavaScript is that an array is loosely typed. Here we're creating a new array of a string Trains, a numeric value 42, and a Boolean value true. So is entries still an instance of array even though we're using different types? What shows in the console? We get true. It's totally valid to use different types within an array. It might be confusing for developers to see that, but it is possible. And here we can see we're setting entries equal to array. We're leaving out the new keyword. Is entries still going to be an instance of array? What shows in the console? We get true. Arrays are so common that JavaScript lets us leave out the new keyword altogether and this is valid. We can also use a bracket notation to create an array. We're not specifying array at all, we're just using brackets to hold Trains, Plains, and Automobiles. What's going to show in the console? True. This is another valid way and a shorthand way of creating arrays. Here we're setting up entries as before, but we're going to log out entries subscript 0. This is the way that we access members of an array, by a subscript with a number. What's going to show in the console? We get Trains. In JavaScript the arrays are zero-based. The first element is referenced by 0, that would be Trains, and then Plains would be referenced by subscript 1, and Automobiles would be referenced by subscript 2. And here's an example of that. What happens when we log out entries What shows in the console? We get Automobiles. Again, Trains is 0, Plains is 1, and Automobiles is 2. So what happens if we try to access entries subscript 3? Automobiles is subscript 2, there is no 3. So what's going to show in the console? We get undefined. And this is very different from other programming languages. No exception gets thrown. There's no notification whatsoever of any kind of error. By rule, undefined gets returned. Another way we can work with arrays is we can pass it the number of elements we want the array to be initialized with. So here we're setting entries equal to new Array(5). What's going to show in the console when we print out entries.length? We get 5. As long as we pass a single numeric value to Array, it's going to initialize the array to that length. So what if we pass in a string of 5 to the array? What's going to show in the console? We get 1. Remember, if we want to initialize the length we need to use a number. But here we're using a string. So the array is going to be composed of 1 string with the number 5. How about this, we're setting entries to brackets, but there's nothing between the brackets. What's going to show in the console? We get 0. So an array is still created, but there's nothing in it. The length is 0. Here we're setting entries to a bracketed array, but there are no values. We have commas that are separating values, but nothing is specified. What is the length of this array going to be? What's going to show in the console? Well most of the time we're going to get 3 in modern browsers, but we're going to get 4 in IE 8 and lower. And this is just confusing. Normally something like this would occur if you're loading information that happens to be blank. You wouldn't really code an array to look like this, but it's just important to know that undefined values do exist between these commas and in modern browsers you're only going to get three values, one for each comma. Now here's a very interesting aspect of arrays in JavaScript. We're setting entries to have two values, Planes and Trains, but then we're setting the length equal to 10. When we log out entries.length, what's going to show in the console? We get 10. So we can actually assign a numeric value to length and the array will take on that new length, even though it only has two elements to start with, Planes and Trains, the other elements will be undefined. Likewise, what if we have two elements in an array, but then we set the length to 1? What are we going to get when we show entries We get undefined. By setting the length to 1, we'll only have the element Planes in the array. So Trains is going to disappear and entries Here we're setting entries to Planes, Trains, and Automobiles and we're setting entries What happens when we log out entries We get Cars. So entries are easily overridden by using the subscript notation. But what about this case, entries is Planes, Trains, and Automobiles, but now we're setting entries equal to Cars. The array is only three elements long, but we're trying to access entries we're going to log out entries We get Cars. So when we assign an entry that's outside of the length of the array, JavaScript is going to go ahead and expand that array, so it started out with a length of 3 and now it has a length of 43. Zero through 42 are valid subscripts. And here we can see an example of that. We have the same example as before, but we're going to log out entries We get Cars and 43, and it's 43 because the subscripts number from 0 to 42, that's 43 values. What if we wanted to append a value to the end of an array? There are a few ways to do it, but here's a simple one. We call entries subscript entries.length and we set it to Bicycles. So essentially we're setting entries subscript 3 to Bicycles. What's going to show in the console? We get 4. The array now has four values. The final value is bicycles. It's also common, especially for debugging purposes, to list out the entries by calling the toString function. What's going to show in the console when we call entries.toString? We get a comma separated list of elements, Planes, Trains, Automobiles. When we're working with numbers we can also use the valueOf function, so we have ratings of 5, 2, and 4 in an array, and what's going to show out in the console when we call ratings.valueOf? Well we get an array of the values and the values are 5, 2, and 4. Another common operation is to join the elements of an array. So we have ratings set to 5, 2, and 4 and we're going to call ratings.join passing in a pipe symbol. What's going to show in the console? We get 5 pipe 2 pipe 4. So by calling join we can separate the array elements with any string, in this case it's a pipe.
Array Features
So we looked at a lot of the fundamentals of arrays, but arrays have a lot more features than what we've seen already. We can use arrays as queues, as stacks, and there are tons of functions we can use to manipulate and search arrays. So let's take a look at the most popular ones. Here we're starting with a blank array, ratings, and we call rates.push(5). So here we're using an array as a stack with the push function. We're also going to push the values 2 and 4 and we're going to log out ratings.length. What shows in the console? We get 3, the values 5, 2, and 4 all get pushed onto the stack or into the array treated as a stack. And we can add as many values as we'd like to push. They'll all get pushed onto the array. So here's a similar example, we're going to push 5, 2, and 4, but then we're going to call ratings.pop. We're going to pop a value off the stack. What's going to show in the console? We get 4. Four was the last value pushed onto the stack, so that's what gets popped off with the pop function. So how about this one, you push the same values 5, 2, and 4, then we pop a value off. What is ratings.length going to be? What's going to show in the console? We get 2. Only the values 5 and 2 are left within the array. Now here we're treating ratings as a stack with the push function, we're going to push 5, 2, and 4, but then we're going to create a variable called firstRating and we're going to call ratings.shift. So we're going to shift the whole array and get the first value. What's going to show in the console? We get 5 because that's the first value. After shift is called, all the values get shifted to the left and the first value, 5, gets taken off. Here's the same example again, expect we're going to log out ratings.length. What's going to show in the console? 2. We started off with three elements in ratings and after the shift we only have two left. Another useful function you'll see is unshift. Here we have the values 5, 2, and 4 being pushed onto the array, but we're going to call ratings.unshift, passing it a value of 3. So this is the exact opposite of shift. What happens when we log out ratings going to be set to? What's going to show in the console? Well we get 3 and 4. Rating unshift function. And newCount is 4, we now have 4 elements in our array. And that's what the unshift function returns, it returns the newCount of the array. Another popular function is concat to concatenate elements onto the end of an array. We're setting up ratings, but then we're creating new ratings and we're setting that to ratings.concat We're passing a new array into concat. What is newRatings.length going to be? What's going to show in the console? We get 6. So we have a brand new array with the values 1 through 6. Concat can take several arguments, here we're calling ratings.concat with an array plus two more random values. These could be anything, not just numbers. What is newRatings.length? What's going to show in the console? We get 8. We start off with 3, we add 4, 5, and 6, and 7 and 8, that's 8 values. So the length is 8. So this example is slightly different. We're creating ratings and newRatings like we did before, but when we call ratings.concat, what does that do to the original ratings array? What is ratings.length? What's going to show in the console? We get 3. The ratings array was never touched. Even though we used it in a concat operation, it was never touched. A completely new ratings array was created named newRatings. Here we have an array, ratings, set to 1, 2, 3, and 4. We're going to call ratings.slice passing it 2. Slice is a very common function on arrays and when we pass it one value, that's going to be an index of where we want to slice the array and create a new array. So what's going to show in the console? We get 3,4. So when we call slice(2), that means it's going to look at ratings subscript 2, which is actually the element number 3. Remember, arrays are zero-based. So our new array is going to contain 3 and everything after that, which is 3 and 4. And that's how we slice an array. We can pass it an index and we'll get that index and everything on within the array. Here we have a similar example, but instead of passing one argument to slice, we're going to pass two arguments. So we know the first argument is going to be the index, index1, and we're also passing it a second index, index3. So what's going to show in the console? We're going to get 2,3. And this is a bit confusing and a source of bugs. When we call slice with two arguments, we do not include the value at the second subscript. So subscript 3 is the value 4 here. I'm going to take everything before that. So we only take the values 2 and 3. So for these two arguments, slice 1 means we're going to start with the value 2, and slice 3 means we're going to take everything before the value 4. So here we have a similar example where we're calling ratings.slice(1,3) and assigning it to newRatings. But we're going to log out ratings.toString, the original array. What's going to show in the console? Well we get the original array, 1, 2, 3, and 4. When we call operations on an array it almost always will create a new array, it doesn't modify the existing array. So ratings is safe. It does not change with slice or many of the other functions that get called on it. Here we're calling slice with an argument of -2. When we have a negative argument, it simply starts counting from the back of the array. So what's going to show in the console? We get 3 and 4. So slice passing it -2 means let's just take the last 2 entries, 3, and 4. Another popular function on arrays is splice, we're setting up ratings, as usual, and we're calling ratings.splice passing it a 1 and a 2. The first argument tells us what index to start at, index number 1, and the 2 says we want to delete 2 items. What's going to show in the console? We get 1,4. So with the splice we're starting at index 1, which is the value 2, and we're going to delete 2 values. We're going to delete 2 and 3 and that's how we get 1,4 as the result. And this is a case where a new array is not being created. Here the original array is getting modified with splice. Here we can see we're calling ratings.splice(0, 1) and we're assigning the result to a variable called removedRating. So what do you think is going to show in the console? We get 1. Splice with return the deleted items as an array, so we're splicing 0, the first element, and we're deleting 1 value. So we'll get an array of 1 with the value 1. Here's another common use of splice with three arguments, we're going to call ratings.splice, we're going to start with number 2, subscript 2 in the array, and we're passing 0, we don't want to delete anything. So nothing is going to be deleted, but we're also passing it a 99, and the 99 will get inserted as a spliced value right at index 2 because that's what we're specifying within the splice. What's going to show in the console? We get 1, 2, 99, 3, and 4. So because we're not deleting anything, the second element is going to be set to 99 and it's going to be inserted right into the middle of the array. And here we can see that splice can be passed an unlimited number of values. The first value is always the index we're going to start at, index 2. The second value is always how many elements do we want to delete, we don't want to delete any, so we're passing 0. And then all the remaining arguments are going to be the values that we insert into the array. So we're going to insert 99, 100, and 101. What's going to show in the console? 1, 2, 99, 100, 101, 3, and 4. So those higher values get inserted directly into the middle of the array with nothing being deleted. And how about this one, we're calling splice. We're going to start with index number 2, but we do want to delete 1 value and we want to insert the value 99. What's going to show in the console? We get 1, 2, 99, and 4. So because we specified 1 for the number of items to delete, the 3 in the original array is going to get deleted and it's going to get replaced with 99. And again, we can splice in as many values as we want. Here we're calling splice starting with element number 2. We're going to delete one element and then splice in three values. So what's going to show in the console? 1, 2, 99, 100, 101, and 4. So with splice we can go ahead and delete values and insert new values. Another operation you might find useful is reverse. We're calling ratings.reverse. What's going to show in the console? 4, 3, 2, 1. So it simply reverses all the elements in an array. How about sort? Recalling sort and the original array is being set to 4, 1, 3, and 2. What's going to show in the console? We get 1, 2, 3, and 4. And this sample is actually a little bit too easy, you're going to run into bugs if you use this too often and let's see why. What if our array consists of 4, 1, 3, 2, and 10 and we call sort on it? What's going to show up in the console? We get 1, 10, 2, 3, and 4. So it's obviously sorting by string values of the elements. We would want 10 to be last, not second. And this is a common problem. So let's see how we can fix this in JavaScript. We can pass a function to sort. So here we're setting up ratings the same way and we're calling ratings.sort, but we're passing it a function. The function takes two arguments, value1, and value2. And we're going to return value1 minus value2. What it's looking for is it's looking for a positive return value if value1 is bigger and it's looking for a negative return value if value2 is bigger. And if they're the same, it's expecting a 0 return value. What's going to show in the console? We get the array sorted properly. We get 1, 2, 3, 4, and 10. And this function can be as complex as we'd like. We can use it to sort objects or strings or any other value. And of course we can also search through arrays. Here we have an array ratings and we're calling ratings.indexOf(3). We're looking for the value 3 and we want to get back its index. What's going to show in the console? Because the value 3 in the array is at location number 2. Remember array indexing is zero-based, so the value 3 is at index number 2. How about this, we have an array of numbers, but we're trying to find the index of a string of value3. What's going to show in the console? We get -1. No conversion is done from a string to a number. So the string just does not exist in the array and when indexOf cannot find a value it returns -1. Likewise, how about this one, we're going to call ratings.indexOf 66. What's going to show in the console? -1. 66 is a number and it doesn't exist in the array. So here we're setting ratings to an array and the first element is 1 and also the last element is 1. What happens when we call ratings.lastIndexOs(1)? This is another common function, lastIndexOf. What's going to show in the console? We get 8. So the search starts at the end of the array when we call lastIndexOf. So it finds 1 as the very last element, which is index 8.
Date Fundamentals
Another commonly used reference type is the date type. In this video we'll look at some of the date functions and by the end of the video we'll show a reference where we can get access to all the information we need to know to work with dates. But let's just look at the fundamentals first. Here we have a new variable called dt and we're setting it to a new date. So what do you think shows in the console? Well we get a huge date printout and it's the current date and time. You can see here that it has some of my local information, such as Pacific Daylight Time. So creating a new date with no arguments gives us the current local date and time. What if we pass a 0 to date? What's going to show in the console? Well dates are special in JavaScript. I'm not sure where this came from, it might have been Unix originally, but dates and times are usually represented as a number and 0 represents January 1 in 1970. And since I'm in Pacific Time we can see that it's actually the day before January 1st, but it's only off by about 8 hours because of the time zone. So remember that passing a 0 to date will give us the standard time of January 1, 1970. We can also pass a month, day, and year to the date constructor. What's going to show in the console? Well we get the day, February 13, 2015, and the time is set to 0. We can also specify a date as the month spelled out and the day of the month with a comma and the year. What's going to show in the console? We do get March 1, 2015 at midnight. What if we pass invalid information to date? We're passing Hi Mom! What do you think is going to happen in this case? What shows in the console? We get an invalid date message. Now we're not getting an exception and you have to be careful of this, a lot of programming languages will throw an exception with invalid data, but here we're just logging out Invalid Date. And we can try to parse a string using Date.parse. What happens in this case? What shows in the console? We get not a number. And you have to watch out for this too. In a lot of cases date works with numbers and we know the number 0 refers to January 1, 1970. And the number represents the number of seconds since that time, but in this case we're trying to parse an invalid string, so we're getting not a number. There's also a UTC function and this way we can pass the year and the month, which is a zero-based month, what do you think is going to show in the console here? Well we get a huge number and that number represents the number of seconds since January 1, 1970 until January 1, 2000. Now numbers aren't very useful to us, so we can usually wrap that number in another data object. Here we're creating a new date and we're passing it that date.UTC function call that we saw in the last example. What do you think is going to show in the console? Now we get a more readable date, it's January 1, 2000. But remember since I'm on Pacific time it's going to be 8 hours earlier in this case. There's a popular function you'll see a lot on date called now. What shows in the console? Again, we get the number of seconds between January 1, 1970 until right now. So to format dates there are several functions we can use. Here we're creating a new date, which is right now, and we're going to call toDateString on that date. What shows in the console? Here we get a very simplified date, Friday September 25, 2015. And how about creating a new date, but we'll call toTimeString on it, what shows in the console? We get the time, hours, minutes, and seconds, and we also get information on the time zone we're in. There are many functions that we can call on date and we'll see a reference website we can use to get all these functions, but for now, here's one called getFullYear. What's going to show in the console? 2015. So that's just going into the date and grabbing out the year part of it and this is very useful when we want to start formatting our own dates for our own logging or for our user interface display. There's also a function on date called setFullYear. Here we're setting the full year of the date to 2025. What's going to show in the console? Well we get 2025, that's pretty straightforward. So we can manipulate these dates however we want. And here I'm at the MDN site , Mozilla Developers Network, and we're looking at the standard built-in object date. You can get here simply by searching for MDN and date. And this is a full reference of everything remotely related to the date object in JavaScript. If we look down we can see a full explanation of the constructor, looking down further we get all the properties and functions related to the date and its prototype. Earlier we were setting and getting the year, but as we can see, we have access to getting the hours and setting the hours, the minutes, the month, and there's probably a function to manipulate the date anyway you want, and this is a very valuable resource. Again, it's the Mozilla Developers Network and it's the reference for the standard built-in object date.
Regular Expressions
The last reference type we'll look at is regular expressions. Regular expressions let us search for patterns within text. They can get very complicated, so we'll just look at some of the fundamental functions and the regular expression object in JavaScript. We'll also look at the MDN website and look at the standard object for regular expressions there. That's the best reference of information, so let's look at some examples. Here we have some blog text, which is the string Sam I Am. And then we'll create a new regular expression object. The object is spelled RegExp, like this. And it can take two arguments, the first argument is the string we're going to search for and in this case it's the simple characters a and m. And the second argument is a flag. In this case the g stands for global. So we're not just interested in the first instance of am, we're going to want all the instances. But for this first example, let's log out pattern instanceof RegExp, just to make sure that we do have a regular expression object. What's going to show in the console? We get true. This is the proper way to set up a regular expression. Now there is a shorthand notation in JavaScript. Here we can see the pattern and we're setting the pattern to /am/g. So the am is what we're searching for and the g is the flag. And to make sure this is valid, let's log out pattern instanceof RegExp. What shows in the console? We get true. So this is another valid way of specifying a pattern for a regular expression. So here we're actually going to use it with a useful function. We're setting our blogText and we have our patterns set up, we're looking for am, and we're going to call the function test on pattern, and we're going to pass it the blog text. So essentially we're going to apply this pattern to the text. What's going to show in the console? We get true. The test function tells us if the pattern matches or not and in this case it does, so we get true as the result. Now for this regular expression we're looking for the string bam. We're going to call pattern.test, passing the blogText. What's going to show in the console? We get false. The string bam does not exist in our blogText, so the result is false. Now we can call pattern.text over and over and we'll usually have some kind of loop if we were doing this in real code. But just to show how it works, we have blogText of Sam I Am and we're looking for an m and we're setting the g flag, which means we're going to continually look throughout the whole string for the character m. So each time we call pattern.test it'll pick up from where it left off. What's going to show in the console? Well we get true at first for the first console.log because the string m is in Sam and for the second function call we also get true because there's an m in Am, at the end of Sam I Am, at the very end. And for the third call to pattern.test we get false. It doesn't show up a third time, so false is returned. There's another function we can use on a regular expression called exec. We're calling pattern.exec blogText. Again, we're searching for m globally. What's going to show in the console? Well we get our first instance of the character m and in the array that's returned we can see m is what we searched for. The index and the string is 2 and the original input string is Sam I Am. So the result of exec gives us a lot of information that we can use. And again, we would have to call exec continually within a loop in order to process all the results, the first instance is in array index 2 of the string. And remember that pattern.exec returns an array and we saw the array elements in the prior example. But if we needed to we could go ahead and pick apart those results using indexing into the array. So when we call pattern.exec passing the blogText, which is result index 0? What shows in the console? Well we get our m, which is what we were searching for. And just remember that we can treat the result of pattern.exec as an array. So in this example, it's exactly the same as the previous one, but we're logging out result.index. Even though result is an array, it has a special property put on it by regular expressions called index, which gives us the index of whatever was found. So what shows in the console? We get 2. We were searching for m and in the string Sam I Am, m first occurs at array index 2. And here's the exact same sample again except we're logging out result.input. So even though result is an array, it has a special property placed on it by the regular expression object called input. What shows in the console? We get Sam I Am, which is the original input into the exec function. And here we see an example of calling pattern.exec several times. We're going to call pattern.exec and we're going to show the index, then we'll call it again and show the index again. What's going to show in the console? We get the number 2 and then the number 7 because the character m shows up as array index 2 in Sam I Am and also as array index 7. So when we're looking globally for multiple results with exec, we just need to put the exec call in some form of loop. And here we have a simple while loop. We'll look for the m and while the result is valid, we'll log it out, and then we'll continuously call exec. What's going to show in the console? Just like before, we get 2 and 7 being logged out. Regular expressions can also be passed into functions on strings. So here look at what we're setting result to. We're setting it to the blogText, which is a string, .match, and match accepts as its first argument the pattern. What's going to show in the console? Well we get an array, which contains our results, m and m. So this is an example of not using the regular expression itself as an object, but rather passing that into the match function on a string. So let's look at the pattern in a little bit more detail here. We're searching for lowercase am and that only occurs once in the string Sam I Am. We have an uppercase A and a lowercase m, but that won't match. So in this example, what's going to show in the console? We get the single value am. It doesn't match the capital Am, so you have to be aware that this pattern is case sensitive. Now in this pattern, we're setting it to the same am string and our flags are different. Our flags are g for global, we're going to look throughout the whole string, and we also have an i there and the i stands for case insensitive. So what do you think is going to show in the console? Now we're matching both the lowercase am and the uppercase Am because we have our i flag for case insensitive. The entire search will be case insensitive. Now I don't want to get too much into the many, many different ways of creating search strings for regular expressions, that's beyond the scope of the course, but one very common one you're going to see are these bracket symbols. We have both an a, lowercase and uppercase, within the bracket symbols. And that just means that either one can match. Notice that I took off the i for case insensitivity. What's going to show in the console? We get both lowercase am and uppercase Am. So the square brackets just give us an option. If any one of those characters exists before the m, it will match. Another common symbol we'll see in regular expressions is the dot symbol. Dot represents any character. So what do you think is going to show in the console? We get am, lowercase and uppercase. So now matter what character comes before an m, it will match the pattern. So again, here I'm at the Mozilla Developers Network and I search for RegExp, r-e-g-e-x-p, which is the regular expression built-on object in JavaScript. And again, there are many ways to use the constructor, there are many functions on its prototype, and the subject of regular expressions is actually a pretty big subject. In this reference we can see all the symbols that make up regular expressions as all well as all the functions that operate on them. So for a full reference on JavaScript regular expressions, you can just visit this site.
Summary
This module has been all about reference types. We started out by looking at the difference between the primitive built-in types and reference types. Then we looked at several examples, mostly dealing with objects, which shows some of the common problems and the differences between primitive and reference types. We looked at arrays, which is a popular reference type object. We also looked at dates and regular expressions. Probably the most common reference type we work with in JavaScript are objects. And we'll be covering those in much greater detail later in the course. So in this module we focused mainly on arrays, dates, and regular expressions.
Objects, JSON, and Prototypes
Introduction
Welcome to this module titled Objects, JSON, and Prototypes. Now we're going to start looking into the extreme details of objects and as a JavaScript programmer we use objects all the time. JSON stands for JavaScript Object Notation and it's simply a way of specifying a new object within JavaScript code. And prototypes is an important aspect of objects in JavaScript. Prototypes give an object somewhat of an inheritance type of functionality. It's different than the kind of inheritance you find in C# or Java, but we'll explain that in detail in this module. So in this module we're going to cover simple objects and JSON. We'll just see how to make an object within our source code. Next we'll go over prototypes in its simplest form. As I just mentioned, prototypes add a little bit of inheritance to a JavaScript object, but we'll look at the exact mechanism that's in place for that. Next we'll see a bunch of examples using prototypes, so that we understand them fully. We'll look at the object.create function, which is important in creating objects and specifying the object's prototype, and we'll look at Object.defineProperty, that's the function that lets us put our own properties onto objects. Now there's an easy way to add a property to an object and then there's the defineProperty function, which gives us much more control over the settings of the property, and we'll look at that in detail. Finally we'll look at miscellaneous object functions and those are just functions on the object prototype that we can work with.
Simple Objects and JSON
Let's start off by looking at simple objects in JavaScript. And also the JavaScript object notation, which is a simple way to create objects in JavaScript source code. In this example we're creating a variable called project and we're setting it a new Object, an object with a capital O, that's our main constructor function for objects in JavaScript. We'll cover constructor functions later in the course, but for now just know that new Object is going to create a new blank object. And we can go ahead and add properties to project by simply specifying a name and value pair on it. So we call project.name, name will become the new property, and we'll assign it Project Phoenix, the value. So what shows in the console when we print out project.name? We get Project Phoenix. So we simply used dot notation on an object to add or set new fields, and that's very simple. Now a field on an object can take pretty much any data type. Here we're creating a new object called project and we're setting project.name to a string, we're setting project.securityLevel to a number, and we're setting project.updateDueDate to a function. So an object can hold date, strings, numbers, Boolean values, as well as functions. So we're going to log out project.updateDueDate as a function call. What's going to show in the console? We get true, which is the returned value of updateDueDate on project. Now there's an alternate way that we can specify properties on an object. Here we have the same example as before, but we're going to log out project and in square brackets we're going to have the string securityLevel. What do you think is going to show in the console? We get 15. So earlier we saw the .notation, we just specified project.securityLevel and using bracket notation is a more flexible way of working with objects and their properties. Let's say security level was stored in a variable, we could just put the variable name there instead of the string security level and those are the two ways we can access properties, with dot notation or with square brackets and the property name as a string. And here we see more of a common situation that we would see in actual source code. The field we would be interested in would be stored in a variable called field right here. And then we would access that field by calling project We get 15. So we have some kind of dynamic access to our objects where we don't need to hardcode the property names. We can use variables and strings to specify property names, by using the bracket notation. Here's another way using JSON to create an object. Notice the open and closing curly braces. We use curly braces to specify an object using JSON and there are no fields between the braces, so we're creating an empty object, then we assign project.name to a string. What do you think is going to show in the console? We get Project Phoenix. So the double curly braces are creating an empty object for us. Now using JSON notation we can start specifying properties for our object. Here we have the opening and closing curly braces and we're going to start specifying fields. Notice the field is called name and it has a colon following it and string Project Phoenix. So this is the basic name value pair that is used to build up objects. We also have the name securityLevel being assigned to 15 and we also have updateDueDate being assigned to a function that returns true. So using JSON notation we can do a lot of what we did before just by specifying project.name, project.securityLevel, and project.updateDueDate, but now it's all encapsulated together within these curly braces and it makes a lot more sense, it's easier to read. So what's going to show in the console when we print out project.name? We get Project Phoenix. With JSON notation we can also specify arrays, so for project we have a new property called team and it's set to three different names and we're going to log out project.team What's going to show in the console? We get Buffy because that's element 2 in the team array. Remember that iguanaboy is going to be index 0, cactusgirl will be index1, and Buffy will be index 2. Arrays are zero-based. Now in JSON you're also going to see this a lot where we're working with arrays of objects. We're setting project equal to a new object and there's one property called tasks and that property is an array. You see the opening and closing braces. But then we have curly braces separated by commas. So each one of these items of tasks is actually its own object. Remember the curly braces start and end a new object in JSON. So the first object has taskName set to first and the second element has taskName set to second. We're going to log out project.tasks Second. Because we're looking at element 1, we're actually looking at that second object in tasks, which is array element 1.
Understanding Prototypes
So we saw JavaScript objects, now we're going to look at prototypes. The concept of prototypes is extremely simple, but it's the downfall of many JavaScript programmers. I'm going to try to give the most simple explanation of prototypes here in this video and then in later videos we'll try to expand upon it and see how it's used in real examples. So every JavaScript object has a prototype property and here's the tricky part, we don't always have access to it. A prototype is something that's maintained internally by JavaScript and only occasionally can we get access to it. And we'll see in this video and other videos how to work with it in more detail, but the important thing really is no matter what object we're using in JavaScript, it does have a property called prototype. And the prototype property is simply an object. There's nothing special about it, it's just an object like any other JavaScript object. So let's look at this source code for a second, we're creating a variable called project and we're just setting it to any object in our code, let's say it's valid, and then on project we want to call someFunction, it could be any function. So the question is, how does JavaScript locate this function? You could say, well it looks at project and it looks to see if that function is attached to project, and you'd be right. But there's more to it than that. Let's take a look at the exact steps the JavaScript engine is going to go through to find someFunction. The first place it's going to look is it's going to look on the project object for someFunction, but what if it doesn't find it there? What if that function just was never set in the first place? That's where the prototype comes in. If it fails to find project.someFunction, it's going to look at project.prototype.someFunction. So it's kind of a unique form of inheritance, if it doesn't find the function on the object itself, it looks on the prototype object. Now remember, we can't always access this prototype field. But just to explain it, I'm adding it here as if we could access it. So again, the first place it looks is project.someFunction. If that doesn't exist it looks at project.prototype.someFunction and it sees if it exists on the prototype object. But what if it doesn't find it there? Then it looks at project.prototype.prototype.someFunction. It looks on the prototype of the prototype. And what if it doesn't find it there? Well here's where we get our prototype chain starting to build up. It looks at project.prototype.prototype.prototype.someFunction. And it's going to look on and on until prototype is set to undefined. And this is how the JavaScript engine resolves function names or even property names. It's going to look on the object, if it doesn't find it on the object, it's going to look on the object's prototype until we hit undefined. And if it doesn't find it anywhere, we get our illegal reference error. Now I mentioned we can't always access object.prototype.prototype.prototype. And that's been a problem in the JavaScript language, so many of the browser created this special symbol. In most browsers we can access the prototype property by using the symbol __proto__. And this is not safe. I think it's the early Internet Explorer versions where this isn't accessible, but even in the modern versions it's not really a JavaScript standard. I think it becomes standardized in ES6 or ECMAScript 2015, but in ES5, which we're covering in this course, it's just something that the browser programmers have implemented as a way to access the prototype object, but it's not something you really want to do in production code. We are going to use it here because it's a great way to learn about prototypes by using this __proto__ symbol. And you'll hear this symbol referred to as underscore proto or sometimes dunder proto, dunder stands for double underscore proto. So when we do use the prototype property, it's most easily accessed on constructor functions and we'll have a module on functions in this course and we'll explain prototype and constructor functions in detail there. But for now, this is all talk and we need to see examples of this prototype in action, and we'll see that in the next video.
Working with Prototypes
So I just gave you some theory on prototypes, but we need to see some real world applications of it. Let's start taking a look at examples. So in this example we have a new object called project and it has one property called name. Now we're going to log out project.foo. Now foo doesn't exist. We only have one field and that's called name. So what's going to show in the console? We get a TypeError, project.foo is not a function. And that makes total sense. We didn't create the function. But I just want to show that we are getting an error here so that you'll understand the next example. So now we have the same object, project, but we're going to log out project.toString. Now we didn't specify a toString function, we just specified a name for our object. So what's going to show in the console? Well we didn't get the error, we got back an object which is pretty much Chrome's way of specifying an object without fields. So there is a function called toString on project, but we didn't specify it. Since this is a video on prototypes, you can guess where the toString function lives, it's on the prototype. Let's take a look. Let's log out the typeof Object.prototype. Now Object with a capital O, that's a constructor function in JavaScript and we haven't covered constructor functions yet, we're going to cover that later. So the approach I'm taking, I'm just going to try to explain prototypes first and then later on you can watch the videos or the module on functions, on constructor functions, and then if you come back here, this will probably make a little bit more sense to you. But there is a global constructor function called Object and it does have a prototype and just to prove it, let's see what shows up in the console. We do get an object. So Object.prototype does exist as an object. And now let's look on that prototype object. Let's get the typeof Object.prototype.toString. Remember before we saw that toString worked, it is a valid function. Does it live on this prototype? What shows in the console? Function. So the toString function does exist and it exists on Object.prototype. It doesn't exist on Object, it exists on Object.prototype. Okay now here's a somewhat simple example with a complex answer. We're creating our project object with a single field name and we want to log out project.prototype. Now unfortunately a prototype is more of an internal JavaScript field and we don't get access to it, so what's going to show in the console? We get undefined. It's not that project doesn't have a prototype, it's just that we don't access to the field.prototype on an object unless it's a construction function, which we'll cover later, but for a JSON object, as we can see being built right here, we cannot access project.prototype. Now if we did want to access project.prototype, this is the way we would do it. We're going to log out the typeof project. dunder proto, again that's __proto__. Sometimes the double underscore proto is shortened to dunder proto. What's going to show in the console? We get our object, which is our prototype object. As mentioned before in this module, the dunder proto field isn't available in several different browsers, mainly the earlier Internet Explorer browsers, I think 10 and earlier, I'm not really sure. But it's not something you really want in your production code. It's only a good way to learn about prototypes. So project does have a prototype called dunder proto and it is set to an object, as we can see here. So we have our project object again and we're going to look at project.__proto__ and we're going to check to see if it is identically equal to Object. Is the prototype of our project Object set to the global object in JavaScript? What shows in the console? False. Remember Object is a constructor function to create new objects. It itself is not a valid prototype, or at least it's not set to project.__proto__. Now hopefully here is where things start to make a little bit more sense. We have our project Object and we're going to compare project.__proto__ to Object.prototype. Remember Object is a constructor function so it does have a valid prototype field. Are these two identically equal? What shows in the console? We get true. So when we create an object with JSON notation, as we can see here, or with a simple new object call, that object's prototype is going to be set to Object.prototype, and that's very important to know because that's the inheritance mechanism that's included in JavaScript. It's very different than C#, C++ or Java, but that's what we get. Every object is going to have a prototype attached to it. And as we can see here, for simple objects in JSON or with a new Object call, prototype is going to be set to Object.prototype. And we'll see how we can work with this a little bit more in future videos.
Object.create() and Prototypes
So we just saw how when we use JSON notation, our prototype for the object gets set to Object.prototype, but what if we don't want that? What if we want our prototype to be set to one of our own objects? We want to get control over how to set that prototype field and we do that with Object.create. Usually we create objects with JSON notation or by calling new Object, but when we're working with prototypes and we want control over the prototypes, we need to use Object.create, and we'll see some examples. So we're creating a new object called project and we're setting the security level property to the value 2. And then on the next line, we're going to call Object.create. Object.create is going to simply create an object, but importantly the first argument is going to become the prototype. We can't set prototype by using an Object.prototype sequence. We need to create a new object using Object.create and passing in the prototype we want. So secretProject is going to be a brand new object and its prototype is going to be set to project. So what's going to show in the console when we print out secretProject.securityLevel? We get the securityLevel of 2. And then again, let's go over that because it's an important concept to grasp. SecretProject is a new empty object created by Object.create, however its prototype is set to project. So when we access secretProject.SecurityLevel, it's not going to find it directly on secretProject, but it is going to find it on the prototype and that's how our answer becomes 2. Now this example shows a little bit of the prototype chain and prototype chaining, and that's how JavaScript resolves symbols. So let's look at this example. This is very similar to the prior example, except we're going to log out typeof secretProject.toString. What's going to show in the console? We get function. So let's see how JavaScript actually finds this toString function. It's going to look at secretProject and secretProject is being set to an empty object, however, its prototype is being set to project. So let's look at project, is there a toString function on project? Nope. However, from our prior video, we saw that when we use a JSON object or create a new object, the prototype is going to be set to Object.prototype and Object.prototype definitely has a toString function on it, that's how we get the answer of function for this question. So this is an example of walking up the prototype chain. SecretProject doesn't have a toString function and its prototype, project, that doesn't have a toString function, but the prototype's prototype does have it. So I'm going to change the format a little bit on these slides because the source code is getting kind of long. Here we have an example that's similar to the last one. We have project as an object, we're creating secretProject as a blank object with a prototype of project, but now we're going to log out secretProject.__proto__ and we're going to test if it's identically equal to Object.prototype. What's going to show in the console? We get false. Again, secretProject has a prototype, but we specified that prototype when we called Object.create and that prototype, otherwise known as project in this case, is not the Object.prototype object. So the answer is false, but how can we make this true? Let's look at the next slide. So now we're setting up our objects the exact same way, but we're going to log out secretProject.__proto__.__proto__. Now we're going to check if that's identically equal to Object.prototype. What's going to show in the console? Now we get true because secretProject has its prototype set to project and project has its prototype set to Object.prototype as we saw in the last video. So now the answer is true. As you build objects in JavaScript, you always want to know what's going on with prototypes, don't let JavaScript take care of it for you. You always want to be able to walk up the chain yourself as if it was some kind of object oriented class hierarchy, just as an analogy, you just want to be sure of what's going on in the prototype chain at all times. And here we need to understand that secretProject.__proto__.__proto___ is identically equal to Object.prototype.
Object.defineProperty()
So we're done with working with prototypes for now. We'll look at prototypes more when we start working with constructor functions. So now let's focus on the defineProperty function on an object. We've worked with lots of properties on an object. You can create them by specifying the Object. and giving the property a name, but sometimes we want a lot more control over properties. There are a lot of flags we can set on properties, such as whether a property is read-only or not, and we need to use defineProperty to get that functionality. And by the way, there's also a function called defineProperties and we'll look at that too, it just lets us define multiple properties in a single call. So let's look at some examples. We're creating a blank object called task and then we're calling object.defineProperty. The first argument is going to be the object that we want to define a property on, which is task. The second argument we're passing text, that's the name of the property. And the third argument is going to be an object and this is a configuration object which we'll look at throughout this video, but the field we're interested in is value. We're going to set the value to Get this job done! So essentially what we're doing is we're going to define a property on the object task, the name of the property is going to be text and its value is going to be Get this job done! So what's going to show in the console? Get this job done! Now it would have a lot easier just to say task.text = Get this job done! That would have been way easier without a function call even, but let's look at some of the cool things that we can do with defineProperty. Now I'm going to be using strict mode in a lot of these examples, mainly because some of the older browsers handle these defineProperty calls differently in some aspects, but using strict mode is something we should always do and it does help make the defineProperty call more consistent. So we're creating a blank variable task, like before, and we're going to call Object.defineProperty, we're going to define a property on task, the name of the property is going to be text, but not only are we setting a value now, but we're also setting writable to true. And then after calling defineProperty we're going to set task.text equal to task.text + now, a string. What's going to show in the console? Get this job done! Now! So the property is writable because we're setting the writable flag to true for the property. Now what if we comment out writable true? Here it's commented out, the rest of the code is the same. What's going to show in the console? TypeError: Cannot assign to read only property. So when we're using defineProperty and we create a property, it's automatically set to read-only. To make it writable we have to set writable to true, but we commented that out for this example. Here we have a similar example, but we're setting enumerable to true. Enumerable is used in for in statements. So here we have a for in statement, we're going to look at every field within task or every property within task, and we're going to log out that field or property. So what's going to show in the console? We get text. We initialize task with no properties, but we add the property text and that's what shows because enumerable is set to true. So what if we comment out enumerable? What's going to show in the console? Well nothing is going to show in the console. By default, enumerable is going to be set to false. It won't show up in a for in statement. Now here's another example. We're setting up a blank task and we're setting our text equal to Get this job done!, but now we're setting configurable to false and right after we set configurable to false we try to configure it. We're going to call defineProperty again and we're going to set text to Done!. What's going to show in the console? TypeError: Cannot redefine property: text. So once we set configurable to false we can't alter it. And what if we set configurable to true? Now we're going to redefine it with Object.defineProperty task, text and setting value to Done! What's going to show in the console? Done! By setting configurable to true we are able to configure it at a later time. Now let's take a look at getter functions using defineProperty. We're creating a task object and it has an _dueDate of 1/15/16, January 15, 2016. Then we're going to define a property on task called dueDate without the underscore. And with defineProperty we can set a getter function by using the getProperty. We set it to a function and we're going to return this._dueDate. What's going to show in the console? We get our date 1/15/16. So by looking at task.dueDate in the call to console.log, we can see that we are calling this getter function and it's returning this._dueDate. This is a simple example, but these getter functions could perform calculations and have a lot more processing going on. Not only can we have getters, we can also have setters. Again, we have a task object with an _dueDate value and we're going to define a getter as well as a setter this time, and in the setter we're going to call this._dueDate and assign it the new value. In our code we're going to call task.dueDate setting it to February 2, 2016. What's going to show in the console? We get 2/2/16, as expected, because when we call this line here, task.dueDate = 2/2/16, this value is eventually going to get signed to this._dueDate right here through the setting function. Now in a lot of cases you're going to want to define more than one property at a time, so there is a function called Object.defineProperties, plural, and it works in a similar way. You pass it a single object task and that's the object that's going to get these new properties. So you can see we're creating two new properties, text and dueDate, and we're setting the values. So what's going to show in the console? We get New Task Due: 1/15/16. We are able to set multiple properties in this manner. When we start working with these custom properties, sometimes we're going to look at what's called the property descriptor and that's just an object that describes this property that we created. In this example we're defining a property called text with a value of New Task, but then we're going to get the descriptor. We're going to call Object.getOwnPropertyDescriptor. We're going to pass it the object, task and we want the descriptor for the text field, and we're going to log it out. What's going to show in the console? Well we get the descriptor object and this has all of the information on what the object is. Its value is New Task, writeable is set to false, enumerable is set to false, and configurable is set to false. And we saw earlier in this video how we could set those configuration properties to true.
Miscellaneous Object Functions
Let's take a look at some important functions that exist on Object.prototype. Some of these functions deal with prototypes in general, so it's important to understand these. Here we're creating a simple object name project, it has a name and a dueDate. So we're going to log out project.hasOwnProperty passing it the argument name. HasOwnProperty as a function exists on Object.prototype and this will tell us if the object itself, not its prototype, has the property name. So what's going to show in the console? We get true because we can see the name property right here, it's directly on project. Now how about this one, we have our same project object, but this time we're going to call the function hasOwnProperty passing it toString. What's going to show in the console? We get false. ToString doesn't belong directly to project, but it will run because it's on project.prototype or more specifically it's on Object.prototype. And just to show that, let's take a look at this example. We have our same project set up, but we're going to call project.__proto__.hasOwnProperty passing it toString. What's going to show in the console? We get true and this just shows what I was talking about on the last slide. Object.prototype is the base object for project, so project.__proto__ does have a toString property. Here's another function we can look at, it's called isPrototypeOf and this tells us if an object is a prototype of the argument we pass, so we're calling Object.prototype.isPrototypeOf(project). What shows in the console? We get true. Project does have a prototype and that prototype is Object.prototype. Here's another example. We're creating a new object called project, setting securityLevel to 2. Then we're going to call Object.create passing it project and assigning that to secretProject. So secretProject will be a brand new object with no fields of its own, but it will have a prototype of project. When we call project.isPrototypeOf(secretProject), will that return true or false? What shows in the console? We get true. Project is definitely the prototype of secretProject because we passed it in Object.create. Now here's another interesting example, our set up is all the same, but we're going to log out Object.prototype.isPrototypeOf(secretProject). So we have secretProject and we know its prototype is project and we know project's prototype is Object.prototype. What shows in the console? We get true. So when we call isPrototypeOf, it will walk the prototype chain, it'll walk through secretProject and then project, and then realize that object.Prototype is a prototype of secretProject. So it does walk the chain. How about this one, our set up is the same again and we're going to log out project.__proto__.isPrototypeOf(secretProject). What shows in the console? True. And this just proves that project.__proto__ is the same as Object.prototype, if we compare this slide to the last one, they are essentially the same. We can also use the in keyword to see if a field exists directly in a certain object. We're setting up secretProject the same as the last few slides and we're going to log out securityLevel as a string this time in secretProject. What's going to show in the console? True. SecurityLevel as a string is a valid object within secretProject, that's what the in operator is all about. How about this one, we have our secretProject set up the same and we're looking for toString in secretProject. What shows in the console? True. So once again, we can see that the in operator is going to walk the prototype chain, it's going to look at secretProject and if that fails it'll look at project's prototype, which is Object.prototype, which does have a toString. So the answer is true. And how about this one, our set up is the same and we're going to log out securityLevel in Object.prototype. What will show in the console? Here we get false. Object.prototype knows nothing about securityLevel. In fact, it's the opposite, project knows everything about securityLevel, but its prototype doesn't, so the answer is false.
Summary
In this module we looked at simple objects and JSON notation. JSON lets us easily create properties for our Objects, directly in the source code. We took a deep look into prototypes. We saw how every object in JavaScript has a prototype, but we can't always access it directly. We saw how we could use the __proto__ symbol to access the prototype, but that's not ready for production until we start working with ES6. We saw several examples of using prototypes and we saw how they chain together and operate together. We looked at the Object.create function in order to create a new object with a given prototype, and this is the key way that we get control over what the prototype is for a new Object. Then we looked at Object.defineProperty. It's very easy to create properties for Objects using dot notation or bracket notation, but sometimes it helps to have a function call. We can pass a lot more information, such as whether the property is writable or enumerable, and even configurable by other defined property calls. Next we look at some miscellaneous object functions. Mainly these functions dealt with the properties of an Object and do certain properties exist within an Object or its prototype and so on. We also saw the in keyword where we can see if a field exists within an object.
Functions
Introduction
Welcome to this module titled Functions. My name is Mark Zamoyta. In this module we'll be looking at functions in a lot more detail than we saw earlier in the course. We'll take a look at function expressions and we'll see how we can give names to our anonymous functions so that we can get some better debugging information. We'll also look at constructor functions. These are very important if we're going to make heavy use of objects in JavaScript. JavaScript doesn't have classes, but the closest we get to a class is one of these constructor functions. One popular one that we have been using all along has been Object with a capital O, but we'll see how we can create our own and use prototypes on them, and then good news is we can directly access a prototype field on a constructor function. We'll take a look at the "this" keyword. "This" can be used in the global namespace, but mostly it's going to be used in a function context. It's important to always understand what "this" refers to because it really changes depending upon the context of the function and how the function is called. We'll look at calling functions directly using the call and apply functions. These are very useful for setting the "this" keyword within the function and also passing arguments. Next we'll take a look at closures. Functions are treated like objects in JavaScript and just like objects, functions can persist. Not only can the function persist, such as if it's assigned to a variable, but it can also access the outside context, the context outside of that function, and we'll see several examples of this. Next we'll look at IIFE's or immediately invoked function expressions. These are used a lot in modern JavaScript programming.
Naming Function Expressions
In this video we'll take a look at naming function expressions and why it might be important to actually name an anonymous function. I'll show you what I'm talking about. Here we have a very simple anonymous function. It's a function expression, we're setting hireEmployee, the variable, to some function. And just for a simple sanity check, what is typeof hireEmployee? What will show in the console? It's a function. So we are working with a valid function expression here. So now within our function, we're going to throw an error. We'll just throw a simple string for now, and then we're going to call the function and what do you think is going to show in the console? Well we do get an uncaught error, which is what we expected, but notice that the message in the console also shows the variable name, hireEmployee. Now we know hireEmployee is a function, but if there were some kind of stack trace, it would show that the function and error is actually an anonymous function. It won't show the variable name. And let's take this example. This is probably more common in JavaScript code. We have our function expression, it's anonymous, but now we're going to create a new variable called action and assign hireEmployee to it. So now we're going to call action passing it an argument, and what do you think is going to show up in the console? Well of course we get our uncaught error, we know that, but it's still saying hireEmployee. This is a little bit misleading. We called a function called action or more directly it was a variable called action, which is a function. So when it comes to debugging large projects, this might start to get a little confusing and a stack trace would also show an anonymous function on top, and that's also confusing. So here's the solution to it. Many developers are starting to do away totally with anonymous functions. We can always give a function a name, as we see here, function myHireEmployeeFn, that's the new name. So it's not anonymous anymore. When we run this, what shows in the console? We get our uncaught error as expected, but now we can see the name of the previously anonymous function. Now it's a named function and debugging is going to be a bit easier and especially looking at stack traces, it's going to tell us exactly where to look. And as JavaScript projects grow in size, you see this a lot more often. Instead of using an anonymous function, just give it a name.
Constructor Functions
In this video we'll take a look at constructor functions. By now you've probably realized that ES5 JavaScript does not have classes. We've already seen how we can use the prototype object or prototype chaining to get some kind of inheritance within objects. And with constructor functions we also get access to a prototype, so understanding prototypes and constructor functions really do go hand in hand. In fact, after watching this video, you might want to go back to the prior module and relook at some of the prototype videos, they could make more sense. So let's start off by looking at Object with a capital O. What shows in the console? We get function. So typeof Object is not object, as you might think, it's actually a constructor function. And by convention, constructor functions always begin with an uppercase letter, that's why we get the uppercase O in Object. It's not a class, it's a constructor function. And here we have an example of a new constructor function, instead of thinking of employee here as a class, it helps to think of it as somewhat of a new data type or a new object type that we can use throughout JavaScript. So to create a constructor function, it's really easy, we just set it to a regular function. You can consider it a simple function expression. And within this function we can access the "this" keyword. "This" refers to the current object, and we'll learn more about "this" later in this module, but for now we can think of "this" as referring to an object that gets passed into the function behind the scenes. So by saying this.name = name, we're taking the argument, name, and assigning it to an object of type employee. Here we have the new keyword and the new keyword is going to create a brand new empty object and it's going to pass this object as the "this" keyword. It doesn't pass the object as an argument, it passes it behind the scenes as this. And the JJ here, that's what gets assigned to name as the argument. So what we'll end up is a brand new object with a name property set to JJ. So looking at what we're logging out, we're logging out typeof newEmployee. What's going to show in the console? We get object. NewEmployee is an object and you can think of it as type Employee with a capital E. Here we have the same example, but we're going to log out something different. We're going to log out newEmployee.name. What shows in the console? We get JJ. We'll create a brand new object and we'll call the constructor function for Employee passing it JJ. So this.name = JJ. And these construct functions, of course, can have multiple arguments and you usually see them written this way. We're setting this.name equal to the name argument and we're setting this.boss to the boss argument. We create the new Employee passing JJ and JD Hogg, so what's going to show in the console when we log out newEmployee.boss? We get JD Hogg. So these do look a lot like class constructors, and these even use the new keyword as in C# or Java, but the functionality is a bit different. We're still missing a lot of the features that other object oriented programming languages have, such as real inheritance and private and public members, and so on. But let's take a look at a few more examples and see how we can work more with prototypes to get more object oriented functionality. So here we have a constructor function called Employee and we're going to create two instances of it, e1 and e2. E1 has a name of JJ and e2 has a name of JV. We're going to compare e1 and we're going to see if that's identically equal to e2. What shows in the console? We get false. So these are two separate unique objects, one has the name JJ and the other has the name JV. They are not identically equal. Now how about this one? We have the same employee constructor function, we're creating our two employees, e1 and e2, and the question is, does e1.__proto__, is that identically equal to e2.__proto__? What shows in the console? We get true. So even though e1 and e2 are very separate objects, they both have the same prototype and that makes it very easy for us to add functionality to all employees. We just add the new functions, not to Employee, but we add the new functions to Employee.prototype. And we'll see some examples coming up. So here we have our Employee constructor function and we're adding a function within the constructor function called giveRaise. The function doesn't do anything, but for this example that's fine. We create our two employees, e1, and e2, and here's the question, does e1.giveRaise, is that identically equal to e2.giveRaise? What shows in the console? False. And that's a problem. What if we have 100,000 objects in our application? This function is going to be duplicated 100,000 times. And that's not good. So in general we don't want to add functions directly to the constructor function, we want to add it to the constructor function.prototype and we'll see an example of that. Now before we take out giveRaise, let's just look at this for a second. What is the type of Employee.prototype? Now remember when we were looking at JSON objects we couldn't do this. We had no access to the JSON object.prototype. But now that we're working with constructor functions, we do have access. And note, I'm not using the __proto_ symbol anymore, __proto__. We're actually spelling out the word prototype. So what shows in the console? We get an object, we get the actual prototype. So always remember, when we're working with construct functions we do have access to .prototype. When we're working with JSON objects we don't, and we have to use a hack, we have to use JSONobject.__proto__. Now here's an important question, we have our constructor function as before and we want to do a test for Employee.prototype, is that identically equal to Object.prototype? What shows in the console? False. We saw earlier how a JSON object has its prototype set to Object.prototype, but now we're dealing with constructor functions, and that's not the case anymore. Employee is going to get its own empty prototype object. And here's an example of how we can take out the giveRaise function to get out of the constructor function and added to the prototype. We call Employee.prototype.giveRaise and we can assign that to an anonymous function or a named function if you want to name it. We'll create two employees, e1 and e2, and we'll ask, is e1.giveRaise, is that identically equal to e2.giveRaise? What shows in the console? True. So now if we have 100,000 objects, our giveRaise function only exists once, and that's an optimization that can be incredibly useful if we have a big application. So let's look at this giveRaise function in a little bit more detail. GiveRaise needs to work on an object, and specifically here we can see that it works on the this object. And using this is very important because that's what differentiates object from object. So when we create an employee we'll give them a salary of 50,000. We'll set up our function and then we'll create 2 new employees, e1 and e2. We're going to give e1 a huge raise. We'll call e1.giveRaise and we'll pass 100,000. He'll like us for that. So the we're going to log out e1.salary and also e2.salary. What's going to show in the console? We get 150,000 and 50,000. So e1 and e2 are being treated as separate objects when we call the giveRaise function. When we called giveRaise with 100,000, we called it off of the e1 object, so this was set by the JavaScript engine to e1. And this is how we make sure that a function on the prototype accesses the correct object by using the this variable.
The this Keyword
In this video we'll take a look at the "this" keyword. This is used as a variable to access some object, either in the global namespace or within a function. Usually we're concerned about it within a function. So in this video we'll take a look at how "this" is used. Now we won't be looking at event handlers. Event handlers have a different way of using the "this" keyword and we'll take a look at that in a future module. So here we're in the global namespace, nothing comes before this code, it's just right there with no function attached. What shows in the console? Object. So we know that this is set to some object in the global namespace, but what object? How about this, let's compare this with window. Is this identically equal to window? What's shows in the console? We get true. Now we're working in a browser right here, if you're working in node, then this won't work. Node doesn't have a window object because it works on a server. So for the purposes of this video, we're only working in a browser. So let's take a look at this example, we'll create a new variable in the global namespace, we'll call it name and we'll assign Jeff to name. We're going to log out this.name. Now we're not logging out just plain old name, we're logging out this.name. What shows in the console? We get Jeff. So in the global area it doesn't matter if you use name or this.name or window.name, they're all the same thing. So now let's take a look at this within a function. We have a function expression, which is anonymous, and we're going to log out this is identically equal to window, true or false? What's going to show in the console? We get true. When we call a function like this in the global namespace without specifying any other object in any way, this still gets assigned to window, but that's not too useful. Let's take a look at some more examples. Here's a more realistic example. We create an object called employee, we use JSON notation, and employee has a field called updateSalary and that function will log out the this variable, and then we'll call employee.updateSalary. What shows in the console? We get our Object. So now that we're working in the context of an object, employee, right here, this will be assigned to the actual object that calls the function, which is employee. Now how about this function? We're setting updateSalary equal to a function. And there's another function within that function, we'll call it fn, and within fn we'll log out the this variable. Also within updateSalary we'll call that function, right here. So what happens when we call employee.updateSalary? What shows in the console? We get our Window object. Even though we're working with employee right here, we're calling another function, and this function has no object attached to it. So this is going to refer to the global object or another name for the global object in a browser is window. And here's another way of doing the exact same thing, we'll test for this and make sure that it's identically equal to window. What shows in the console? True. So here we have a constructor function called Address and just as a sample, it'll accept line 1 of the Address. We'll new the keyword and we'll new up an Address, 123 State St. So within the function we'll assign 123 State St. as line 1 to this.line1 and then we'll log out the keyword this. What's going to show in the console? We get our object, Address. And the reason we get this is because this is a feature of the new operator. New creates a new object and when it calls the constructor function, this gets assigned to the object that new created, and we saw this earlier in this module. So it's important to remember that when we use new, this will be assigned to the brand new object created by new. So how about this example, we have our constructor function, Address, and we're adding a function to the prototype, and we're going to look at what this is within the prototype. We'll new up an Address and we'll call addr.updateZipCode. What's going to show in the console? We get our Address, line1 is equal to 123 State St. So when we call updateZipCode we can see that it's actually attached to a real object and this object gets assigned to this within the prototype function call.
Calling Functions
Let's take a look at a different way of calling functions. Calling functions the normal way is easy. You just specify the function name and add some parenthesis and that's about it. But there are a lot of cases where we want to take control over the this variable within a function, and that's why we use call and apply. If you ever look at the source code for jQuery or Angular, you'll see tons of calls to call and apply. And again, the main reason you'd want to use these is to get control over what this is set to within a function. Let's take this example, we have a simple function expression, it's anonymous, we're setting it to updateZipCode and then we call that function. What shows in the console? We get our Window object. We saw that in the last video. But now we're going to call updateZipCode and instead of calling it directly, we're going to add a .call function call to it. And within the parenthesis we'll pass an empty object. What do you think is going to show up in the console? We get our empty Object. So the call function lets us pass an object, which becomes the this keyword and this variable within that function. And this is very important when you're creating advanced libraries or you have an advanced object structure. How about this, we'll call updateZipCode.call and we'll pass it an object that has a property of zip set to 11787. What shows in the console? We get our Object and we can see that the object has that same property. So again, when we take a function, such as updateZipCode, instead of calling that function directly by putting parenthesis after it, instead we can just add a .call for the call function, passing it the object which becomes this within the function. Now it's much more likely that we're going to be passing a variable to call, as we can see here we're calling it with zipCode and zipCode is just another object. What shows in the console? Our same Object with our zipCode. So this is similar to the prior examples, expect it's more common that we're going to be calling call with some variable name. Now what happens if our function requires arguments? Here the function needs a new zipCode and a country. Well we call the call function, passing it the zipCode as the new this object, but we can also pass our arguments after it. We'll pass in a zipCode, 11888, and we'll pass in US for a country. What shows in the console? We get 11888 US. So remember, for the call function we separate the arguments after our object zipCode, we separate the arguments with commas. And now let's look at the aply function call. This is the same example as the prior one, except instead of calling call, we're calling apply. But instead of passing a comma separate list, we're going to pass an array and the apply function will break down this array into arguments to pass to the function. And again, this is much more realistic. In complex code, you're not always going to know how many arguments to pass to a function. It's a lot easier just to put the arguments in an array, not matter what the length, and pass that array into the function. So what's going to show in the console? Again we get 11888 US. The apply function broke down this array of arguments into newZip and country. And just to show my point, here's another similar example, but we're going to call apply without the array. We'll pass a comma separated listed of arguments. What do you think is going to show up in the console? Yep, we get an error. Uncaught TypeError: Function.Prototype.apply: Arguments list has wrong type. So just remember with .apply, you need to pass it an array of arguments, with .call you need to pass it a comma separated list of arguments.
Closures
Let's take a look at closures in JavaScript. Sometimes you want a function to persist. You want to be able to use that function over and over, even if you've already called it. And not only do you want the function to exist, you want the entire context of that function to exist. So that includes the function and all of the variables in its parent functions. Let's see an example of a closure. Here we have a function expression, we're setting salaryUpdater to a function. You can see that we're setting a current salary, and then we have a property called generator, which itself is a function. Now we saw earlier on this course how we can easily access the parent functions properties, we're setting the currentSalary equal to itself times 2 and then we return the currentSalary. Also notice that we're returning the generator. We're returning that function. Now closures occur at runtime. You can consider a closure as a function that persists. Functions are a lot like objects in JavaScript. They get created, they have a lifecycle, and then they get garbage collected when they can't be called anymore. And in a closure we want to prevent that garbage collection. We want to hold onto a function. So let's take a look at this code. We're creating a new variable, updateFn, and we're setting it to salaryUpdater(50000). So our salaryUpdater function gets called and our internal function gets returned. So now we have a closure. UpdateFn is the closure and it points back to this generator function, and one of the big benefits of the closure now is that we can access the context of the function. We can get access to currentSalary right here, even though it exists in a parent function. So currentSalary gets initialized to 50,000 and then in our console.log call we're going to call updateFn, so our closure function will execute. What shows in the console? We get 100,000. UpdateFn is going to persist, as long as that's in scope the function will exist along with its context and we'll always be able to access currentSalary through the function. So we get 50,000 times 2, that's our answer. So here we have a similar example, everything is the same except we're going to call updateFn twice, just to show that this function and its context is persisting. So we pass in 50000 to salaryUpdater, then we call updateFn and then we'll call updateFn again, this time logging it out. What's going to show in the console? We get 70000. We have the initial 50000 and then for each call to updateFn it's going to increase the currentsalary by 10000. So we can see that we do have a closure and currentSalary is persisting. And there are a few different ways to get these functions to persist. Here we're returning one and as long as we hold on to that return value, we'll have access to the closure. But very commonly you're going to see things like events hold on to functions. Event handlers are a common place to see closures because say we're monitoring a mouse movement, the callback function needs to persist. You also see closures a lot in timer functions. If you call set interval and you're calling a function regularly, you want that function to exist and it could be used as a closure. So those are the three common situations where we use closures. Here where we return a function from another function, as an event handler, and also as a set interval function.
IIFEs
Let's take a look at immediately invoked function expressions, otherwise known as IIFEs. An IIFE is a function that gets executed immediately and the main purpose of it is to prevent your code from polluting the global namespace. Let's see some examples. So here we have a function, it's an anonymous function, and it simply logs out the word executed. You'll notice that we have parenthesis before function and after the curly brace at the end. By doing this and then by calling this function, with the open and close parenthesis, we create what's called the IIFE. This function is going to be immediately invoked. We're not declaring any variables in it right now, but we'll see that soon. What shows in the console? Executed! The function gets called mainly because we have these parenthesis here. Now if we look at this closing parenthesis, sometimes you'll see this before the semicolon. Let's see an example of that. So here we move the right parenthesis right before the semicolon and either of these two techniques are fine. They both work exactly the same and there are arguments each way, which one is best, but when it comes down to it you're going to see it done both ways in code that you view. So what's going to show in the console? The exact same thing, Executed! Now here we have another IIFE. We have a function and it has its own variable, employeeName. So employeeName, because we're using the var keyword, is going to be in the scope of the function, it's not going to be in the global scope. So what do you think is going to show in the console? We get Uncaught Reference Error: employeeName is not defined. So employeeName here within the function is in the function scope, and employeeName here is in the global scope. So you can see that an IIFE does not pollute the global environment. We can add whatever variables we want in this function and they'll only be accessible by this function. Now here's a very common pattern having to do with IIFEs. There seems to be an unwritten rule where every application and every library can have one single global variable, for example, jQuery has the jQuery variable, Angular has the Angular variable, and an application usually has a variable in the global namespace called app or the name of the app. So here we have an object called app and it's empty for now, but in a real app it would be populated, and we want to use an IIFE. We want to start working with this app object and not have to worry about things happening globally in the global namespace. So we can pass this app object into our IIFE function. We're passing it right here and we're going to rename it to ns for namespace. We could just as well name it app, but every once in a while you're going to run across the app being called a namespace, a place to store variables for the app. So the function sets ns.name equal to none. There's no name. And then we're going to call console.log and we're going to write out app.name. What's going to show in the console? None. That's the value we set it to. And you'll see this often. You can pass an object or anything into an IIFE and use it internally within the function. Now let's assume we have jQuery loaded up, which is very common. One thing you might see is a call to an IIFE like this. We'll pass the app object, that'll get renamed to namespace, ns, or you could call it app, and we'll pass jQuery, the jQuery global object. And we're going to name that $. The reason why you see this is because some code might actually alter the dollar sign symbol, but this way the IIFE is guaranteed that the $ will equal jQuery. So we're setting ns.name equal to none again, and we're going to log out $ is identically equal to jQuery. What shows in the console? We get true. So this way we can guarantee that we can use the $ as our jQuery global variable. Another thing you'll see is undefined being one of the arguments to the IIFE function. Now notice undefined is the third argument, but we're only passing in two arguments to the function. This will make sure that the system's undefined object will get set to undefined. In some older JavaScript code and you actually see it in some modern JavaScript code too, you'll see the keyword undefined redefined, and that's a pretty bad practice. It confuses a lot of people and it just really makes the code hard to follow. Most developers now agree that we should just leave undefined alone. But you will see this type of code on stack overflow and in some older code and maybe if you need it as a safety check now, you might end up writing code like this yourself. So what shows in the console? We get the string undefined. And this is what the system considers to be undefined. Another technique of using an IIFE is to do away with the first set of parenthesis. You'll notice here we have the function and we're calling the function, but instead of the parenthesis we have a unary operator. We could use a plus or a minus or even an exclamation point as the not symbol, but the whole idea is to create a function expression. And if we left off the plus sign it wouldn't work. We need either the parenthesis, which we've been seeing all along, or we need some kind of symbol to turn it into an expression. So when it comes to IIFEs, just beware that you're not always wrapping the function in parenthesis. Sometimes they'll be some other technique such as this, a plus sign, to turn it into an expression, even though the plus sign in meaningless. Now you'll notice we're going to log out Executed within the IIFE and we're going to log out employeeName outside of the IIFE. What shows in the console? We get Executed! and we also get an Uncaught ReferenceError: employeeName is not defined. So even though we're not using parenthesis, we're using a unary operator and that's good enough to create an IIFE. And again, employeeName is not in the global namespace, it's in the namespace of the IIFE. So that's why we get our Uncaught ReferenceError.
Recursion
Recursion refers to a function's ability to call itself. In this course we're not going to get into all of the patterns of recursion, but we will look at one of the unique things about JavaScript and a way to fix a common problem with recursion. So let's start off with some hierarchical data. We're setting orgChart equal to a simple orgChart for a small company. We have Michael and he has one subordinate. Andy and has Andy has two subordinates, Dwight and Kevin. So this is the JSON object we'll be dealing with and we want to use recursion to dig into this structure to get out all of the names. So we'll create a function, we'll assign it to the variable fn, and we'll pass it the topEmployee, that's the employee who we want to get all the subordinates for. We'll log out the name and then we'll loop through the subordinates. I will go from 0 to the topEmployee.subordinates.length and we'll increment i. And then we use recursion. So for each person in this orgChart, we're going to recall this function called fn. And then finally, we'll kick everything off by passing it the orgChart. So Michael will be the topEmployee to begin with. What do you think is going to show in the console? We get Michael, Andy, Dwight, and Kevin. So this code is working fine. It goes through our data and it picks up each individual by using recursion. Mainly it's this call to fn right here, which is the recursive call. Now let's see a common problem with this. All of our setup data is the same and our recursive function is the same, but now we're going to assign fn to a new variable called fn2 and this is very common in JavaScript, a lot of times you treat a function as a variable and you reassign it. So what happens in this case? We have fn2 equal to fn, but then we decide to set fn equal to null. So what's going to happen with fn2? We're going to call fn2 passing it orgChart. What shows in the console? Well we get Michael to show up, but then we get an Uncaught TypeError: fn is not a function. So right here we can see the call to fn and this is where our error is. We changed the name of the function essentially. What we did is we wiped out fn as a valid function name. Fn2 still exists and that's why we get the name Michael, but fn no longer exists, we're nulling it out. No how do we fix this? Well, here we can see we don't have an anonymous function anymore, we're naming the function. So fn is a function expression that is named. So instead of calling fn here, we call showAllEmployees. So now what happens? We set fn to fn2 and we null out fn. We call fn2 orgChart. What's going to show in the console? We get our names, Michael, Andy, Dwight, and Kevin. So this is another big benefit of using named functions rather than anonymous functions. As variables get nulled out a recursive function will still work.
Summary
In this module we looked at function expressions, specifically the importance of naming them. Using anonymous work well and you see it all over the place, but we saw how error messages and stack traces can make a lot more sense if you name your anonymous functions. We looked at the this keyword. The value of "this" varies depending upon how a function is called, what scope it's in, whether it's the global scope or a function scope, and the arguments passed to call or apply. We'll see later in this course how this also changes in regard to a function being called as an event handler. There's a whole module on events where we'll look at this. We took a look at calling functions using call and apply. These functions allow us to assign the this value to a function. We took a look at closures where a function persists and has access to its entire context. We usually create closures by returning a child function of a bigger function where closures can be created and used as event handlers or by timer functions, such as set interval. Next we look at IIFEs, immediately invoked function expressions. IIFEs are important so that we can keep variables out of the global namespace. And we looked at recursion. When a function is able to call itself, it's a lot safer to not use an anonymous function, but rather give it a name.
Programming the BOM and DOM
Introduction
Welcome to this module titled Programming the BOM and DOM. BOM stands for browser object model and that's a set of objects that the browser exposes to JavaScript. Likewise, the DOM is the document object model. That represents the document that the browser is showing, and again, it exposes objects to JavaScript so we can work with the document. So in this module we'll be taking a look at the window Object. Window is the global Object in the browser that gives us information about the viewport within the browser and lots of other information. If you're using JavaScript only on Node.js, this is going to be useless, there is no browser window. Instead you'd use the global Object, and again, we're not going to be covering that in this course. We're going to be focusing on the browser in the document here. Next we're going to be taking a look at the system dialogs. These are the simple dialogs that the browser puts up that accept user input. These are styled differently in all the different major browsers, so if you wanted a consistent look across browsers, you wouldn't use these, but they are very useful for testing and utility applications and that kind of thing. Next we'll look at the location Object, which is contained in the window Object, but it lets us know the URL that we're looking at in the browser. Then we'll start looking at the HTML document. We'll see how to access it as a bunch of objects within JavaScript. And finally we'll look at query selectors, which is the most modern way of selecting elements within the HTML document. Interacting with the document object model is usually done through a library such as jQuery. But with query selectors in modern browsers, we can do away with that to some degree. So let's take a look at the window Object first.
The window Object and Timers
Let's take a look at the window Object and Timers. You would think timers would be part of the JavaScript specification, but they're actually not. They're a part of the browser and they can be accessed by the window Object. By timers I mean the set interval and the set time out function calls. So we're going to take a look at a very few of the many properties of window and we'll take a look at timers as well. Here you can see we're accessing window.screenLeft and window.screenTop, and this is going to give us the location of the visible screen within the browser on the computer screen. So what shows in the console? Well it all depends on where your browser window is located. You can see here I have it in the top left corner. I placed it off by 1 pixel. More common properties that we need from window are things such as innterWidth and outerWidth. InnerWidth refers to the size of the page viewport. This is where your HTML document is actually showing. The browser usually has some kind of frame and that's included in the outerWidth. What shows in the console? Well it depends on the size of your viewport. You can see here mine is 1189 and the outerWidth, the width of the browser itself is 1201. So the sides of the browser are 6 pixels on each side. One of the most popular things to do with a window Object is to open a new page. Here we're calling window.open and we're passing it www.Pluralsight.com. And we want it to show up in a blank page. So will a window actually open up? Well it really depends upon the user's settings. Usually browsers come with popups disabled by default, so you'd probably be prompted by the browser to open up this new window. Let's take a look at timers now. We have one line of setup here. We're going to grab the current date and we're going to log out the seconds from that date. And then we call setTimeout, which is a function which is part of the browser, but we can access it from the global Object window. We don't need to prefix it with window., it's a global function. So when we call setTimeout, we're going to send it a function and the number of milliseconds to wait before we call that function. So when this internal function gets called, it'll be 1 second after setTimeout is called. Inside this function we'll do the same thing, we'll grab the current date and we'll print out the seconds. What shows in the console? Well I got 6 and 7, so whatever the time was it was 6 seconds into the minute and then 1 second later it was 7 seconds into the minute. Let's see another example. Now here we're going to do a similar thing. We're going to log out the seconds, but now when we call setTimeout it's going to return an id for us and we're going to use that id. We're going to call clearTimeout and that's going to clear the timer for us, as long as we pass it a valid id, which we are. So what do you think is going to show in the console? Well I got 31, it was 31 seconds into the minute and we did not get a second number. And this just proves that our setTimeout function did not get called after a second because we cancelled the timer. Here instead of setTimeout, we're going to be calling setInterval, and this will call the past function over and over again every 1000 milliseconds, which is 1 second. Within this function we'll grab the seconds and we'll log them out. If the seconds happen to be 10, we'll cancel the timer. We have a closure going on here, we're accessing id which exists in an outside function. So what do you think is going to show up in the console? Well when I ran it, it went 7, 8, 9, 10 and then the timer stopped. Looking back we can see when the seconds equals 10, we're going to clearInterval. We're going to shut down the timer. And we can safely do that within the function, the key is to keep track of the id when we call setInterval.
System Dialogs
There are three key system dialogs we can use for testing and debugging, simple applications, but for a more polished app you probably don't want to use these. Each browser implements it in a different way with a different style. So let's take a look at what these three system dialogs are. First of all we have alert and this is used to show some text in a dismissible dialog. What's the result in the browser? The system dialog says Hello World! Let's take a look at that. Here I'm in Chrome and I'll refresh the page and we can see the dialog that pops up, the page at localhost port number says Hello World! And in Chrome I have the option of preventing this page from creating additional dialogs, which is great, but other browsers don't necessarily do that. And we can dismiss it with the Close button or the OK button. Next we have the confirm dialog. We're passing it the message Delete EVERYTHING?! and if it returns a truthy expression, we'll log out You asked for it!, otherwise we'll log out "Maybe next time… So what's going to be the result in the browser and console? A system dialog asks Delete EVERYTHING?! and let's take a look at that. The browser shows a dialog saying the page at localhost port number says Delete EVERYTHING?!, but now we have an OK and a Cancel button. Let's click OK and see what happens. In our console we get You asked for it! Let's refresh and click Cancel. We get Maybe next time…, but what happens if we close out the dialog with the close button right here? We also get Maybe next time… And in the final system dialog we can actually prompt for some text. We want the user to type something and the function is called prompt and we're asking for your name. What shows in the browser and the console? Well we're going to get null if the user doesn't enter anything, but if the user does type something it'll show up in the console, and let's see what that looks like. We get the page at localhost: port number says Your name? and I'm able to type in characters. I'll select OK and my name, Mark, shows up in the console. Let's refresh and this time I won't enter anything. I'll click OK and nothing shows in the console.
The location Object
Let's take a look at the location Object. This is a property of the global Object, which lets us look at the browser's URL location and we can also modify it as well. Here we're going to log out location.href. What shows in the console? Here we'll get the entire URL of the document we're looking at, in this case it's a simple HTML page on my own local server. What about location.host? What shows in the console? Well here we only get the host name and the port number. How about location.port? What shows in the console? Yep, we just get the port number. How about location.protocol? What shows in the console? We get http along with the colon. And here we're calling location.assign and we're passing it http://www.Pluralsight.com. What occurs in the browser? Well hopefully we would get the browser to redirect to Pluralsight.com, but just because we have this code in our JavaScript doesn't mean it's going to execute. It really depends upon the user's settings, but calling location.assign is the way to get the browser to point to a different document.
Document Basics
Let's take a look at what it takes to work with an HTML document in JavaScript. Accessing the document has changed over time and the most modern way to do it is with query selectors, which we'll see in the next video, but you'll still run into lots and lots of code that uses the functions described in this video, so let's take a look at some examples. Here we have part of the body of an HTML page and this is what we'll be working with. We have an article, you can see the beginning and the closing tags, and let's give the article an id of article1. It includes an h3 tag for a title and 3 paragraphs. Now for simplicity I'm just showing the HTML on top and the JavaScript on the bottom here. Of course these would be in separate files or at least the JavaScript would be included in script tags. So when this JavaScript code does execute, you can see that JavaScript gets us access to the document property, which is the HTML document, and we're calling getElementById, passing it article1. We're assigning this to a variable called element and we're logging it out. What shows in the console? Well we get our complete article tag, element now refers to this complete article and we can look at it and manipulate it within JavaScript. And again, that's by calling getElementById, as long as the element has an id. Here we have another example with the same HTML, but instead of calling getElementById, we're calling document.getElementsByTagName passing it p, and then we'll log out elements. What shows in the console? Well we get an array of our 3 paragraphs, paragraph 1, 2, and 3. So here the paragraphs don't need IDs, we're just getting the elements by the tag name. I changed up the HTML a little bit, two of our paragraphs now have a class set to special. In the JavaScript we're calling document.getElementsByClassName, passing it special. Then we're logging out elements. What shows in the console? We get an array of our two paragraphs with the special class. So we saw how to get elements by ID, by the tag name, and now by the class name. In this example you can see that I added a class of my-custom-class to article. In the JavaScript we're calling document.getElementById article1, we've seen that before, but now we're going to log out a, which is our variable here, a.getAttribute class. What shows in the console? We get my-custom-class. Once we find an element, we can examine the attributes with the getAttribute function call, we just pass it the name of the attribute we want to look at. Here we're using the same HTML again, we're calling getElementByID article1, assigning that to a, but now we're going to call a.setAttribute. We pass it the attribute name and then its value. Here it's dynamic-style. We'll log out a.getAttribute class. What shows in the console? Dynamic-style. So once we have an element we can look at an attribute with the getAttribute function call, but we can set an attribute as well. Here we do it by calling a.setAttribute passing the attribute name and its value. Here we have an article with the h4 tag and a paragraph tag. We'll grab the article like before by ID and we're going to log out a.childNodes. What shows in the console? We get all the childNodes of our selected element, the article element. Now you notice we have our h4 and our p tags in here, but we have whitespace in between. So those show up as text nodes. We have the whitespace before h4, between h4 and the paragraph, and after the paragraph, and it's important to watch out for that because you might just be expecting the h4 and the p tag to be returned.
Query Selectors
Let's take a look at query selectors. There's really a lot to working with the DOM in JavaScript, and you can go to your favorite reference to find out all the properties and functions. I prefer MDN, the Mozilla Developer's Network, but there are lots of choices out there for documentation. Let's take a look at the most common features of query selectors now. As in the last video, I'll put some HTML on top and underneath it I'll put some JavaScript. This isn't the way it would be in your source code, but I'm doing this just for a presentation. So we have an article, just like we saw in the last video, and it's pretty straightforward. Let's look at the JavaScript code. We're calling document.querySelector, and this lets us query the document in the fastest way possible. We're calling querySelector, passing it article, and we're assigning all of this to element and logging it out. What shows in the console? We get our complete article tag. That's what we asked for and that's what we got. But a lot of times we're going to need to be more specific than just grabbing an article tag. So our article has an id of article1, we'll call document.querySelector #article1 or a hash article1. What shows in the console? We get the same article tag. We use the # symbol to represent and id and these are the same symbols as used in CSS. Here we're calling document.querySelector .special. What shows in the console? Well we get only the first paragraph that has a class of special. The dot, like in CSS, represents the class name. So when we call querySelector passing it .special, we'll get back the first match, the first element that has a class of special. And what if we wanted to get back all of those classes? We can call document.querySelectorAll, passing it .special. What shows in the console? Yep, we get both the paragraphs now. So it's important to know that querySelector will return the first match, but querySelectorAll will select everything as an array.
Summary
In this course we looked at the browser object model and the document object model. We took a look at some of the window Object properties and we saw how to access some of the properties of the viewport as well as change the URL in the browser. We looked at system dialogs. These are common alerts and prompts that show up, but they're styled differently in different browsers. We looked at the location Object where we can get detailed information on the URL that we're looking at as well as resetting it. Then we looked at document basics. We saw how to access elements within an HTML document. Finally, we looked at query selectors, which is a more modern way of accessing DOM elements.
Event Handlers
Introduction
Hi this is Mark Zamoyta. This module is titled Event Handlers. Events are a big part of JavaScript. They usually fire off from some kind of user interaction or some kind of system messages from the browser or device we're working on. In this module we'll see how to write functions to handle these events when the occur. We'll start off by looking at many categories of events, there are dozens of them, and we'll briefly go over each one. Next we'll look at the event object. When an event gets fired, the JavaScript runtime engine will create an object to go along with the event and it's a pretty big object with a lot of properties and we'll take a look at some of those key properties we'll need to use. Next we'll look at handling events. Among all the major web browsers, nothing has changed as much as event handling. Standards weren't in place early on in JavaScript's development and there's just tons of legacy code and even current code that uses older techniques of event handling. We'll take a look at a few of these techniques. And then we'll take a look at the more modern way of using event listeners. This is a more powerful and simplified approach and it works well among modern browsers. Next we'll take a look at event bubbling. Bubbling has to do with parent/child relationships. Let's say we had a form and the form had a button on it, the form's the parent, the button is the child. If you click the button, who receives an event first? Does the parent receive the event or does the button receive the event? This has long been a problem with JavaScript, but we can handle it easily with modern event listeners, and we'll see how to do that. So let's get started and look at several categories of events.
Events
Events play a big part in JavaScript. Let's take a look at some of the many events that can fire off in our code. We'll start by looking at user interface events. These are fired by the browser or the user interacting with the browser. Load is fired when a web page has loaded and when a web page unloads there's an unload event. There's an abort event if loading gets interrupted and an error event in case something goes wrong in the browser. Select is used for selecting text, whether the user selects it with a mouse, keyboard or other device. Resize is when the viewport resizes. And scroll is fired when the user scrolls the web page. And there are events for the mouse and the mouse wheel. Let's look at some of these. There's the click event for a mouse click and sometimes for a touch on a touch screen. There's a double click event, mousedown, mouseenter, mouseleave. So mouseenter and mouseleave fire as the mouse cursor enters the rectangular area of a DOM element. There's mousemove, mouseout, mouseover, mouseup, and mousewheel to handle the mouse wheel. Each of these has unique properties in the event object and we won't be going over these in this course. You can check out all the details on the Mozilla Developers Network. There are keyboard and text events. There's keydown, keypress, keyup, and textInput, and textInput would be used on a text field in a form. There are focus events for forms, as various controls gain and release focus. There's blur, which means a control has lost focus. There's focus, receiving focus, focusin, and focusout. Focusin and focusout are different than blur and focus in that they work with bubbling. Bubbling has to do with the parent/child relationship and we'll see more about that later in this module. Then we have two specific HTML5 events, we have contextmenu for bringing up what would usually be a right click in Windows context menu, and beforeunload, which is an event we can check to make sure the user really wants to unload a page. When this is handled, normally you'll see a message such as; do you really want to exit this page? And that just helps us make sure we save information on a form. Then there are touch events, these are for touch devices and these change very much from device to device, so if you use these, make sure you test them on all target devices. There's a touchstart where you put your finger down, a touchmove and a touchend. There's also a touchcancel with the touch is cancelled before ending. So those are all the key events. In the next video let's take a look at the event object.
The Event Object
Let's take a quick look at the event object. This is an object created by the JavaScript runtime engine which gets passed to an event handler. Let's just go over the key properties on this object. First of all, all these properties are read only. There are a few functions and we can call those, we just can't change them. So bubbles is going to be true or false based upon whether or not this event bubbles up to the parents or not. Cancelable will let us know whether or not we can cancel any kind of propagation of this event. CurrentTarget is the DOM element that we're currently looking at. DefaultPrevented is a Boolean value telling us if prevent default was called. We'll see that in a second. The detail property holds extra information about the event. EventPhase will be 1, 2, or 3. One means it's at the capture phase, which is the opposite of bubbling, it's going in the other direction of bubbling. Two means we're at the target. And three means that we're in the process of bubbling. To prevent the browser from executing any kind of default behavior, for example, if we had a Submit button on a form, we could prevent that Submit button from actually doing the submission. Likewise if we had a link with an anchor tag, we can prevent the browser from following that link. So we have stopImmediatePropagation and stopPropagation. The difference between these two is that stopPropogation will stop all event capture and bubbling, but stopImmediatePropogation will also make sure that no more handlers get called. Target is the original target of this event, so if we click on a button and the event starts to bubble up from parent to parent to parent, target will be set to that original button. Trusted will be true if the event comes from the browser and it will be false if the event is triggered through JavaScript code from a developer. And type is simply the name of the event, for example, it would be the string click for a click event.
Handling Events
Let's take a look at handling events and as I mentioned earlier, event handling has changed a lot over the years and we'll start off by looking at one of the first ways we could work with events and these techniques are still valid in modern browsers. Here we have some markup, which is in the body of an HTML page. It's an input tag type button and here we can see an attribute called onclick. We can take any event name and prefix it with on and then use that in an element, as we can see here. We're setting onclick to some JavaScript code. What shows in the browser when the button is pressed? Well the code executes and the system dialog says foo. This isn't the recommended way to execute code, but it's perfectly valid. When we put JavaScript code directly in the markup, it may get lost or other developers might not be aware of it. So it's a much better idea to keep JavaScript in its own file or at least within a script tag. Here's another example of calling an event handler for onclick and the code we're going to execute is a function call called submitForm and in a totally separate file, a JavaScript file this time, we'll declare our submitForm function. What shows in the console when the button is pressed? We get in submitForm. So the JavaScript function will execute and the key problem with this is that we need to make sure the JavaScript file loads before the user actually clicks on the input button. Here's a similar example, except this time we're calling submitForm and we're passing it the this variable. This is different in event handlers than it is as we saw earlier in the course. Essentially this is going to be set to the DOM element we're working with. What shows in the console when the button is pressed? We get submit1. This becomes the input tag or the input element itself and it has an ID of submit1, so when we log out to the console, we see submit1, the ID. Here's another similar example, except this time we're calling submitForm with this and event. Event will get set to the event object, as we saw in a prior video. This could be very important and contain necessary data in order to handle the event properly, so it's very common to pass the event object along. And we're going to log out the event.type. Type is simply a string for the name of the event. What shows in the console when the button is pressed? We get click. We're handling onclick so the event.type is set to click, the actual event name. And again, this isn't the usual or normal way to be calling JavaScript code from HTML. These are just examples that you'll see out there in existing code or on stack overflow and so on. But we'll see shortly the proper way to be doing this. Here we have another example where now we're actually going to extract all of the JavaScript code out of HTML. We're a step closer, but things aren't perfect yet. So we have our input button and notice there's no more code associated with it directly. When a JavaScript file executes we're going to call document.getElementById submit1. So we'll grab our button. And then at that point from JavaScript we can assign a function to button.onclick. So we wire up our event this way. What shows in the console when the button is pressed? Button Clicked. We get our string, so our function does execute. So we can access onclick as an attribute to the input tag in HTML or we can access it on the DOM element within JavaScript, as we see here. Here's an example similar to the last, expect we're setting button.onclick equal to null. So we're essentially wiping out our event handler. What shows in the console when the button is pressed? Well we get nothing. Any code can come along and just wipe out our event handler and that's the source of a lot of bugs, and that's why there is a better way of handling events.
Event Listeners
Event listeners are the most modern way of handling events. If you're writing applications for modern browsers, you definitely want to be using event listeners. If you need to support older browsers, you're probably best off using a library such as jQuery, but event listeners handle several other problems found in previous methods of handling events. Let's take a look. In our HTML we have an input button again and in our JavaScript file we grab our button. We call document.getElementById passing the Id of the button. Once we have the DOM element we can simply call DOM element.addEventListener. There are two main arguments, the first one is the name of the event we want to handle and the second one is the handler function. What shows in the console when the button is pressed? We get Button Clicked. So this is a valid way of setting up events and it's probably the best way if you're working in modern browsers. One of the benefits of event listeners is that we can work with multiple handlers on a single DOM element. Here we grab out button and then we call addEventListener twice. What shows in the console when the button is pressed? We get Button Clicked and then Another Listener Function. So each one of these listener functions gets executed on a button click and we can have as many listeners as we'd like. Here's actually a better way to call addEventListener. Notice down here we're calling button.addEventListener passing it the click event and we're passing it a function expression. So submitHandler is defined right here. This could be an anonymous function, but we're giving it a name, formSubmitHandler. So we don't need to take our function and insert it directly into the addEventListener call like we saw before. We're using an external function, and this could be more flexible on a few situations, but it's also going to be necessary to remove an event listener, as we'll see soon, but for this example, what shows in the console when the button is pressed? In formSubmitHandler. So our function does get called. In this example our setup is the same, except we're going to call addEventListener and then right after it we'll call removeEventListener, passing it the event name and the handler function. What shows in the console when the button is pressed? We get nothing. We use removeEventListener to remove a handler function, and notice that we have to actually pass the handler function that we want to remove. And that way our code won't interfere with other code that might be handling the same event.
Event Bubbling
Let's take a look at event bubbling. Many times controls are going to overlap on a webpage. If we look at the example of a form with a submit button, if we click that submit button, does the event go to the form first or to the button first? Let's say it goes to the button first. We may want that event to bubble up to the form so that we can handle it at the form level as well. In other scenarios we might want the form to handle the event first and then have the button handle the event later. So we need to get control over this bubbling mechanism. Let's see some examples. Here we have a snippet of HTML from the body of a webpage. Before we look at it in too much detail, let's see what this page shows. So we simply have a blue square and that will be the parent div and then that has a child div, which is simply a red square. So the big blue square is the parent and the small red square is its child. So the markup is pretty straightforward, instead of using a style sheet I'm just entering a style attribute here. It has a width and a height and a background color of blue. The child div has a background color of red. And here's our JavaScript code. We grab div1 and we grab div2 and we set up a handler. This event handler is simply going to log out this.id. So if you remember, the handler sets the this keyword to the current DOM element. So depending upon which div gets called, this will print out either div1 or div2, the Id of the clicked div, and then we're going to set up the clickHandler. We call addEventListener, click, and we pass it the clickHandler. Now the third argument is false and we'll be working with that later in this video, but for now just know that we're setting up div1.addEventListener and div2.addEventListener to the same handler function. So what shows in the console when div2 is pressed? That would be the red child div. We get div2 and div1, so the red square, div2, gets processed first and that bubbles up to div1, its parent, and then div1 has a chance to handle the event. Notice how we're passing false here as the third argument to addEventListener and this is what allows for the bubbling. Here we have the same example except now we're setting true as the third argument to addEventListener. What shows in the console when div2 is pressed? Remember div2 is the child red square. Now we get div1 and then div2. So when we pass true as the third argument to addEventListener, the parent div has the first chance to handle the event and then after that its child gets a chance. This is sometimes called the capture phase where a parent captures the event before its children get a chance to. Let's take this example, everything's the same as the last example, except now we're calling event.stopPropagation. Remember event is something that's passed in as the first argument to every event handler and we'll call event.stopPropagation. What shows in the console when div2 is pressed? We get just div1. Div1 gets a chance to handle the event and it decides to stop propagating the event, so the child are never going to get a chance to handle it. Here's another similar example, the only change is this line here, event.preventDefault. We're not going to be able to see this one in action, but preventDefault is used a lot with stopPropagation. We want to prevent the default action of whatever was clicked, for example, if we click the link, we don't want to follow the link, or if we clicked on a submit button on a form, the form might be invalid so we'd call event.preventDefault to prevent the form from being submitted. And you'll see these two used in tandem often. So what shows in the console when div2 is pressed? Again, we only get div1. StopPropagation prevents div2 from ever seeing the event.
Summary
In this module we took a look at many of the different categories of events. and we saw how events usually deal with user interaction with the browser or device or also system messages from the browser. We took a look at the event object, once we start handling events, the event object is very important because it has the properties which give us all the details about the event itself. Next we took a look at handling events. We started with the earliest form of event handling, which happened directly in the HTML, and we saw how that gradually started moving out of the HTML and into JavaScript, to the point where not it's the best practice just to leave all your JavaScript in its own JavaScript file and put nothing in an HTML handler. Next we looked at event listeners. Using event listeners is the most modern way to handle events. They work great in modern browsers and if you need access to earlier browsers, it's probably best to be using jQuery or some similar library. Lastly, we looked at event bubbling. It's always important to know whether or not a parent is going to receive an event first before it's child or if the child will receive the event first and have that bubble up to the parent.
Built-in Objects and Functions
Introduction
Hi this Mark Zamoyta and this module is titled Built-in Objects and Functions. We're been looking at built-in objects and functions throughout the course, but a few have fallen through the cracks and we want to make sure we cover everything important. We'll start off this module by looking at global functions. These are just utility functions that we can access anywhere in JavaScript. Next we'll look at the math object. And we've already looked at the string object, but we're going to go into a lot more detail on its functions. Finally we'll look at the arguments variable. When a function is executing we have access to a special variable called arguments and this is just an alternative way to access the arguments. So let's start off by looking at global functions now.
Global Functions
Let's take a look at examples of some of JavaScript's global functions. These functions deal with things such as parsing numbers, encoding and decoding strings, and using the eval function to execute code. Here's our first global function, parseInt, it parses an integer. What shows in the console? Simply enough we get 1234 and that's a very straightforward parse. But what about this, we're adding a b ASCII character before the integer. What do you think is going to show in the console? NaN, not a number. As soon as the parser hits something it doesn't understand, it will end parsing. So in this case we don't have anything valid. How about this, we're calling parseInt with a string of 12z34? What shows in the console? We get 12. So the parser was able to find a valid integer and as soon as it saw the z character, it stopped parsing. Here we're calling parseInt, but we're passing it a floating point value. What shows in the console? 1234. So parseInt doesn't do any rounding for us. It notices the decimal point and ends the parsing right there. What if we try to parse a simple space? What shows in the console? Not a number. There is a second argument to parseInt that's optional, here we're passing in 16 as the radix, so the string will be base 16, a hex number. What shows in the console? 46152, and that's simply the decimal form of the hex C000. So we've been parsing integers up until now, but there's also a parseFloat function. What shows in the console? 123.9, that's straightforward. And again, what happens if we add an invalid numeric value to the beginning of the string? Here we have a z. What shows in the console? Not a number. So it works in a similar way to parseInt. We can also use exponential notation. Here we're parsing a value of 1239e-1. So the e-1 means move the decimal place 1 position to the left. What shows in the console? 123.9. So parsing a float with an exponential number in there works fine. Another global function is isFinite and this is used to test whether or not a number is set to one of the infinities or not. Remember there is Number.POSITIVE_INFINITY and there's also a Number.NEGATIVE_INFINITY and this will return true or false. What shows in the console? False. We don't have a finite number. How about this one, we're going to call isFinite passing it the number 42. What shows in the console? True. That's a finite number. And for testing not a number, there's an isNaN function. What shows in the console? We get true. And how about this, we're calling is not a number and we're passing it 9 divided by 0. Most languages would through an exception, but not JavaScript. What do you think is going to show in the console? False. If you remember earlier in the course 9 divided by 0 is actually infinity, so is not a number on infinity is false. And to show that, let's call isFinite on 9 divided by 0. What shows in the console? False. As mentioned, 9 divided by 0 is infinite. Let's look at encoding and decoding some strings now using global functions. Let's say we have a path variable as set here and we want to encode it for transmission. There's a global function, encodeURI, and we pass it the string we want to encode. What shows in the console? Well if a backslash is represented as %5C, the answer makes sense. We have backslash start and backslash. In JavaScript two backslashes translate into a single slash within a string literal. Now here's a similar example, except we're adding a plus sign to the end of the string. Do you think encodeURI is going to encode the plus symbol? What shows in the console? Well we get our answer from before, but it does not encode the plus symbol. Now how do you keep track of which symbols get encoded and which symbols don't? Let's take a look at MDN. So I'm here at the Mozilla Developer's Network and you can just search to the standard built-in objects page. If we scroll way down, here we can see encodeURI and decodeURI and there's also an encodeURIComponent and a decodeURIComponent. Let's look at encodeURI, that's the function we were looking at an example of. If we scroll down we can see exactly which characters will encode and decode. And our plus symbol is right here, so that's not going to be encoded as we saw. And this is a very valuable reference. A lot of exceptions pop up when you're working with encoding and decoding characters and this tells us exactly what we'll get encoded and decoded. Also in the examples we'll see shortly that there's an encode URI component, which has a different set of symbols. Let's look at that briefly. And here we can see that encodeURIComponent does escape everything except for these characters here. So again, this is a really valuable resource. So we have our plus sign at the end of the string and it did not encode. So now let's call encodeURIComponent on the path with the plus sign. What shows in the console? Now our plus sign is going to be encoded to %2B. Likewise, for encodeURI, there's also a decodeURI function. What shows in the console? \start\+, the %5C represents the backslash character. And how about this one, we'll decodeURIComponent path. What shows in the console? \start\+. So again, the codeURIComponent does handle the + symbol. The final global function we'll look at is eval. In general you want to avoid calling eval because it can execute code from any string. It really opens up your code and people's systems to injection attacks and other types of attacks. And let's see an example of that. Here we're setting globalVar equal to foo just to have an example of a global variable, and then we're setting a variable called code to some JavaScript. The JavaScript command is console.log and we're passing it globalVar. Then we're going to call eval code, which essentially is going to compile and run this code right there, so the question is, can eval actually access this global variable? What shows in the console? Foo. So anything passed to eval can access global variables and if there's malicious code in there, there could be big trouble with your application. That's why a lot of developers just avoid the eval function altogether.
The Math Object
Let's look at JavaScript's built-in math object. There are tons of functions on math and you can look at MDN or some other online reference to get access to all of them, but we'll cover some of the important ones now. First of all, there is a constant called Math.PI. What shows in the console? 3.14 and so on. That's the floating point value of PI. We can call Math.abs to get the absolute value of a number. What shows in the console? 42, the negative sign is removed. There's as function ceil for ceiling. This won't round or truncate the number, instead it will raise the number up to the next highest integer. What shows in the console? We get 12. And the opposite of ceiling is floor. What shows in the console? 11. So we pretty much get a truncation there. And we also have a standard trunc function for truncate. So whether the number is positive or negative, it's going to truncate the decimal part and return the integer part of the number. What shows in the console? 42. We can call the Math.max function to find the maximum value. Notice that we can pass as many arguments as we'd like to it. We're passing -12, 0, 12, and 88 as a string. What shows in the console? We get 88. So there was an implicit conversion from a string to a number and that's going to be common when we're working with the math object and its functions. How about Math.min to find the minimum value? What shows in the console? -12. We can call Math.pow for power to raise a number to a certain exponent. So here we're going to take 2 and we're going to raise it to the third power. What shows in the console? 8. And math does have a random number generator. We can just call the function random. What shows in the console? We'll get a random value between 0 and 1. We can call Math.sqrt for square root. What shows in the console? 9. And what about calling a square root of a negative number? What shows in the console? Not a number.
The String Object
We've been working with strings throughout this course, but now let's take a closer look at some of the string object's important functions. Here we're setting value to a string and we'll call the charAt function. This will locate a character at a certain index, in this case index 3. What shows in the console? Capital S. Remember arrays or strings, in this case, are zero-based, so the m in my would be index 0. We saw how to use the plus symbol earlier in the course for string concatenation, but there's also a concat function. What shows in the console? My String Lives! and that's a simple concatenation. We can easily test a string for a given substring. Here we're calling value.includes to see if the space character is included in that string. It'll return a Boolean value. What shows in the console? True, it does have a space. There's also en endsWith function, which will let us know if a string ends with a certain value. What shows in the console? True. It does end in ing. Now how about this one, let's call endsWith, but instead of passing it ing we'll add a space at the end. What shows in the console? False. So it doesn't do any kind of trimming on the string, we have to be precise with it. For searching there's an indexOf function. We'll call value.indexOf passing it a capital M. What shows in the console? 0. We get the index of the capital M, which is a 0. If it couldn't find it we'd get a -1. And here's an example of that, we'll call indexOf and we'll pass a capital Z. What shows in the console? We get our -1. There's a function called lastIndexOf and this lets us search the string starting at the end of the string. What shows in the console? 5. The capital S in string is at array index 5. A string also has a slice function. Here we're passing slice an index of 5, which as we just saw is the capital S in String. What shows in the console? We get the word string. So it essentially took a slice of the original string, starting at index 5. And we can also pass a second argument to slice. Here we're passing it 5, 8. So we want to start out slice at index 5 and we want to take everything up to, but not including index 8. What shows in the console? Str. And it's important to remember that the first argument, this index is included, but for the second argument, 8 here, we're looking for everything to that point, but not including it. Here we're calling slice passing it a -3, having a negative value just means it's going to look from the end of the string, so it'll slice the string 3 characters in from the end. What shows in the console? Ing, the final three characters. We can easily split a string into an array by calling the split function. We need to pass it the character to split on, here it's a space. An array is returned and here we're looking at the length. What shows in the console? 2. The array will consist of Some and String. JavaScript has a few substring functions and here's the first one, substr, for substring. This function takes the starting position and the length. What shows in the console? Some. So it starts at index 0 and takes 4 characters. Now just to make things extra confusing, there's also a substring function that's spelled out. In the prior example the function name was substr, but here it's substring. The difference is that substring, spelled out here, takes the starting index and the ending index, but the ending index is not inclusive. What shows in the console? We get the capital S for string. And again, when we pass the second index, 6, this will not be included in the output. We only want to look at the string up to that point. So here's the same example and instead of substring spelled out, let's call substr with the values 5 and 6. What shows in the console? String. Remember for substr, not spelled out, the second argument refers to the number of characters to get.
Arguments
The last built-in object we'll look at is arguments. Arguments exist in every function and normally we access arguments from the argument list, the comma separated list in the declaration. But sometimes we might have variable length arguments or we just don't know what's coming into a function. And we can use the arguments property or variable to look at it. Let's see examples. Here we have a function expression and it simply logs out arguments.length. We'll call validateValues and we'll pass it three arguments, 1, true, and settings. What shows in the console? 3. So even though our function expression has an empty list of arguments here we can still get access to any arguments passed to the function. Here's a similar example except we're going to log out arguments subscript 0. What shows in the console? The value 1. So we can treat arguments as an array and access the argument values that way. Here we see an example where we're actually setting an argument. We're setting arguments, subscript 0, to 9, and then we're going to log it out. What do you think is going to show in the console? 9. So we do have write access to these arguments. And this might be useful if we're adjusting settings or we want to do some kind of argument clean up before we execute code.
Summary
In this module we looked at JavaScript's global functions. We worked with parsing integers and floats, encoding and decoding strings, and the eval function. We took a look at the Math object and saw we could use the PI constant and many mathematical functions that you would expect. We took a deeper look at the string object and some of its functions, and finally we looked at the arguments value. Every function can access its arguments with the built-in arguments variable and we saw how to use that to read and even write over arguments to a function.
Miscellaneous JavaScript Topics
Introduction
Hi this is Mark Zamoyta and welcome to the final module is this course, Miscellaneous JavaScript Topics. It's one thing to understand the JavaScript language itself inside out, but there are a lot of tools we need to use as JavaScript developers and we'll be covering several of them in this module. We'll start off by looking at error handling and promises. JavaScript does have a try, catch, finally construct as seen in other languages. But that actually takes a smaller role in JavaScript. Usually when it comes to error handling in JavaScript, you see a lot happening with promises and a promise is simply a pattern developed upon JavaScript. Next we'll take a look at strict mode. Throughout this course we've been turning strict mode on and off to see the difference in how JavaScript handles our code and in this module we'll consolidate some of that information and look at it as a whole. There are two important tools in JavaScript to help us write better code, JSLint and JSHint. We'll take a look at these and we'll see the difference and how it can help us write better code. Finally we'll look at using modules in JavaScript. There are a few different specifications for writing modules and we'll take a look at them at a high level and we'll look at a good modern way to be writing modules and packages in JavaScript. So let's get started and take a look at error handling.
Error Handling Using try, catch, finally
Let's take a look at error handling in JavaScript. Now we do have the try, catch, finally construct in JavaScript and if you come from C# or Java or some other language, that might be familiar to you. So we'll cover that here in this video, but more than likely what you're going to be using for error handling is going to be something like promises or jQuery's deferred objects or some pattern along those lines. With that being said, the try, catch, finally blocks do come in useful in JavaScript and let's take a look at some examples. So here we have a try block and a catch block. And we're just going to go ahead and throw a new error in our code. And because we're throwing an error, the catch block will execute. Notice that we're throwing a new error. We need to create a new instance of our error object and we pass it the message which here is just Custom Error. In our catch block this single argument will refer to the error, here it's the variable e. So what's going to show in the console? We get Error, which is the name of the error, - Custom Error, which is the message. And this catch block will only execute in case an error gets thrown. Here we have a similar example, except we're adding a finally block. So the code in our try block will execute, if there's an error our catch block will catch it, but whether if there's an error or not, our finally block will still execute no matter what. What shows in the console? We get Error - Custom Error and then we get our Finally done message. So even though an error was thrown, our finally block still executed. Here's another example, but we're not throwing an error now. We're simply setting a variable. And our catch block won't execute, we're not throwing an error and we're not doing anything in JavaScript that would raise an error. What shows in the console? Finally done. So in this case there was no error thrown and the finally block still executes, whether there was an error or not. Now it's one thing to catch errors, but sometimes in our catch clause we want to find out which error was thrown. And we can use the instanceof operator on our error object to compare it to a given error name. Here we're calling e instanceof RangeError to see if e actually is a range error. What shows in the console? RangeError. So the variable e, which is our error object, is an instance of Range Error in this case. So if we had to test for various errors and handle each one differently, we could just use multiple if statements such as this, comparing e against an error data type. In the next video we'll talk about promises and a little bit about observables.
Promises and Observables
I want to talk a little bit about promises because that's one of the popular patterns we'll see for error handling in JavaScript. And there's a new emerging pattern called observables. Promises are a lot more prevalent now than observables at this point in time, but the observable pattern really is picking up steam, so we'll take a look at that too. I'm here at GitHub.com and I'm looking at a repository called kriskowal\q and q is a very popular promise library in JavaScript. Reading the tag line it says, a tool for creating and composing asynchronous promises in JavaScript. And let's go to the link. Here you can read all about promises, and I won't be going into detail on this in this course or in this video, but if we just scroll down a little bit on this page, we can see what promises are about. Instead of having this kind of complex nested error handling, but can get very confusing to read, we use a promise pattern which you can see down here. We create functions to handle each step of the process, whether it's code we want to execute in a .then call or if it's code we want to execute when we catch an error, or if it's a function or code we want to execute when the promise resolves and it's done. To learn more about promises, there's a good Pluralsight course titled JavaScript Design Patterns by Aaron Powell. Looking at this course, we can see the module on promises right here and I highly recommend this to get started with promises. Also if you're working with jQuery you can read up on promises and deferred objects at the jQuery site. Now I also mentioned observables. I'm at a GitHub repository called Reactive-Extensions/RxJS and this is an implementation of the observable pattern. Observables take promises to the next level and there's a lot of momentum behind this pattern now. It is something that could catch on in a big way in the near future. You can read more about observables here at this GitHub repository or if we click on the link in the tag line, we go to the ReactiveX IO page, an API for asynchronous programming with observable streams. I'll click on Introduction and you can find out all about observables and the observer pattern here.
Strict Mode
Let's take a look at strict mode in JavaScript. We're been looking at strict mode throughout this course to see the difference between executing code in strict mode compared to the non-strict mode, and in this video we'll specifically be looking at the key things we need to watch out for. Generally it's a good idea to always be working in strict mode. It really helps you write better code and it detects errors that you might not otherwise find. The way to enter strict mode is by specifying a string and the string evaluates to use strict, as we see here. It might seem strange to have a string just sitting there not being assigned to a variable, but that is how we enter strict mode. So this function will be compiled and executed in strict mode, however, code outside of this function will not. Now we could place the use strict string on top in the global area, and that would apply to the global area as well as this function, and it's up to you as the developer to determine whether you want all your JavaScript to be in strict mode or just certain functions. Just keep in mind that if you're pulling in third party libraries and you specify use strict in a global area, you could run into problems if the third party library isn't meant for strict mode. So in this example we'll execute this function actNow, which is going to set newVar equal to 9. What shows in the console? We can an Uncaught ReferenceError: newVar is not defined. And this is one of the most important aspects of strict mode. It forces us to define variables. It won't create a new variable in the global namespace. Here's a similar example, but we're not entering strict mode. What shows in the console? Well we don't get any errors here. We're assigning the value 9 to newVar and because we're not using the var keyword in front of newVar, we'll be placing this variable in the global namespace. And most likely that's not what the author of this code intended. Here we have another example where we're creating a variable within the function called newVar, but then we're deleting it. The delete operator removes the variable from the context, in this case it's the context of the function. What shows in the console? We don't get any errors because this is perfectly valid JavaScript code. We create a variable and then we delete it. We won't be making any other reference to it. Now in this example, it's the same as the prior example except we're entering strict mode. What do you think is going to show in the console? We get an Uncaught SyntaxError: Delete of an unqualified identifier in strict mode. So we cannot use the delete operator in strict mode. In strict mode if we declare a variable, we're not going to be able to get rid of it. Here's another example in non-strict mode. You can see here that we're creating a function expression, passing it two arguments of the same name, a and a. What shows in the console? Well we don't get any errors, but just looking at the code it's very confusing. Both the arguments have the same name. But now we enter strict mode, what shows in the console? We get an Uncaught SyntaxError: Duplicate parameter name not allowed in this context. So in strict mode we're not allowed to have duplicate parameter names, which is great. Here we're creating an object and then we're using a with statement, which will use that object. One of the problems with the with statement is that by simple entering a typo into a name, you could be creating global variables. So for this code outside of strict mode, what shows in the console? We get no errors, it's perfectly fine to use a with statement. And here's the same example, but we're entering strict mode. What shows in the console? Uncaught SyntaxError: Strict mode code may not include a with statement. So the with statement is not allowed in strict mode and that's fine. A lot of developers avoid the with statement anyway. So we covered some of the main reasons for using strict mode, but there are a lot more subtle reasons. I won't go into those in detail, but you can check out MDN and search for strict mode. You'll get a great article that covers every aspect of strict mode and what you can and can't do with it.
JSLint and JSHint
There are two tools that are very useful to JavaScript developers, JSLint and JSHint. If you're not familiar with linters, they're very useful in evaluating your source code and looking for errors before you even compile. These tools are available in all the major IDEs and developer text editors. They're usually going to be available as packages that you can install and there is a big difference between JSLint and JSHint. Let's start off by looking at JSLint. I'm here at www.jslint.com and if you wanted to you could go ahead and start entering source code and you can look at the types of errors that would come up. I've already created slides for these, so we won't do that just yet, but I'll click on the read the instructions link, and here you can read all about JSLint. It will find errors in your source code before you even execute it. Now it doesn't just look for syntax errors, it looks for any kind of error, whether it be in styling, forgetting a semicolon, or any other kind of problem with your code. One of the problems that arose with JSLint is that it's not the most configurable utility out there, and that's where JSHint comes in. We're at the JSHint website, jshint.com, and here you can also enter some code and see which kinds of errors pop up. I'm going to click the About button and we can see the tag line is JSHint, A Static Code Analysis Tool for JavaScript. So this is very similar to JSLint and is even built on top of it, I believe, but it adds a level of configuration. There are some cases where JSLint is just doing too much and you want to be able to shut off certain errors and that's what JSHint excels at. So you can find out more about JSLint and JSHint at these websites and you also want to make sure that whatever IDE or whatever programmer editor you're using, you want to install the packages for JSLint and/or JSHint. So let's look at a few examples of the types of things you might run into when using JSHint and/or JSLint. Here we have a constructor function and then we're creating an instance right here and logging out the instances Id. And all of this is valid code, but let's take a look at what JSLint would tell us about this code. What shows in the console? We get Unexpected 'this' and we get Undeclared 'console'. So the Unexpected 'this' is referring to the this keyword right here, and while this is valid JavaScript code, JSLint does not like it, and this is one of the main reasons people move over to JSHint is to suppress this kind of warning, even though some developers might not like using the this keyword, for other developers it's fine. Likewise, we get our Undeclared 'console' warning. Console isn't part of the JavaScript language, but all the browsers use it, it's a very valuable debug tool. So this is another type of error that you might want to suppress. So here we have a similar example except this time we're not entering strict mode. What shows in the console? Expected 'use strict' before 'this'. So JSLint wants us to be in strict mode, and that's probably a good thing. Here we have another similar example, except we're leaving out the var keyword before Id. What shows in the console? Undeclared 'id', and this is where tools such as JSLint and JSHint really shine. They catch this kind of problem, which is almost certainly a programmer's error, and there are hundreds of errors that these tools will catch. So to find out more you can visit the websites mentioned previously in this video.
Modular JavaScript
When we work in JavaScript it's a really good idea to be working with modules. We want to be able to reuse our code in as many projects as needed or possible. And it's also a good idea to remove any kind of dependencies among modules, that way we get the maximum code reuse. And over the years several different patterns have evolved on how to use modules within JavaScript. AMD stands for Asynchronous Module Definition and that's a popular pattern mainly on the browser side. When Node.js started gaining in popularity they leaned more towards a different option called CommonJS. So the general rule has been CommonJS is more likely to be used on the server side, while AMD is more likely to be used on the front end browser side, and that's a very loose rule. But the key thing to know is that these two definitions and patterns are not compatible. And there's a whole new module syntax defined in ES6, also called ECMAScript 2015. And that seems to be the way things are moving right now, but it really hasn't caught on in a big way yet, at least at this point in time. What is catching on is some kind of use of SystemJS. SystemJS is more of a universal module loader and it can work with AMD, CommonJS, and ES6 syntax. And we're seeing SystemJS used more and more widely. Let's take a look at its website. I'm at the GitHub repository called systemjs/systemjs and the tag line says universal dynamic module loader. If we scroll down, you can see here that it does load any module format and that's why it's gaining in popularity. If you want to learn more about SystemJS and then associated package manager, there's a great Pluralsight course to learn about this. The title is Modern, Modular JavaScript with SystemJS and jspm. Jspm is a JavaScript package manager. So if you're interested in working with SystemJS and jspm, I highly recommend this course.
Summary
In this module we looked at several valuable tools that every JavaScript developer needs to know. First of all we looked at error handling. We looked at the try, catch, finally blocks and syntax and we looked at promises and a little bit at observables. We talked a bit about strict mode and we saw some examples of how strict mode helps us prevent bugs. And also for preventing bugs we looked at JSLint and JSHint. Finally, we looked at Modular JavaScript. We want to write modular code to maximize our code reuse and we looked at the current technologies used for creating modules, mainly, the AMD pattern, CommonJS, the new ES6 syntax, and also SystemJS, which ties everything together.
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
(524)
My rating
Duration5h 43m
Released7 Jan 2016
Share course