Transcripts
1. Why is it important to understand the difference?: in this class, I'll explain the difference between scope and context and JavaScript. I'll also help you to understand why scoping context may sometimes feel like the same thing even though they're not. And I'll also explain how to make better decisions about scoping context when planning your code. The third question that we need to answer is. Why is it so important to understand the difference between scope and context in JavaScript ? Well, as a developer, you spend the majority of your time doing one of two things development or troubleshooting . And when it comes to development, if you have a strong understanding of the difference between scope and context, you'll write code that is cleaner and easier to maintain. And that's because you'll make better decisions about how to best leverage, scope and context in your code when it comes troubleshooting. If you understand the difference between scope and context, you'll make the best use of your time and take the right troubleshooting steps to solve your problem quicker. So later on in this course will talk about how to make better decisions about leveraging scope and context in your code. So right now I just want to focus on troubleshooting. Let's take a look at a typical troubleshooting workflow. So let's say, have a problem or a bug. Now, in most cases, you discover the bug, and you immediately start taking steps to troubleshoot that problem. And if you don't really understand the difference between scope in context, you might find that your troubleshooting steps are kind of all over the place. One thing lead you to another, and one minute you think it's a problem with the variable. And then maybe it's a context problem because it's a property of an object. But then you're not really sure, and it leads you down a different path. And at this 0.1 thing that's clear is we don't have ah, very focused game plan and are troubleshooting steps are not, um, really leading us anyplace in a logical way. So the problem here is that without a really solid understanding of a difference between scope and context, you could find that your troubleshooting could take a long time. It could be unfocused, and there's a chance that you may never actually get the problem solved. I think there's a better way to do this, so when you start out with a problem or a bug. If the first thing you do is ask yourself a question, Is this a scope or a context problem? Now, if you ask yourself that question but first, before you take any troubleshooting steps, if you have the knowledge to answer that question, if you understand the difference between scope and context and you can answer this question confidently, then you can make the right decision. And once you know the answer to that question, then the troubleshooting steps that you take on more logical. They're more focused, and you can solve your problem much more quickly. So when it comes to troubleshooting, understanding the different teams, scoping context helps you to troubleshoot the problem more easily. And it's important that when you start troubleshooting a problem, you want to ask yourself a question. Is this a scope or a context? Problems of the first step is determining if the problem is a scope or a context problems. The second step is to then take the appropriate troubleshooting steps based on the answer to part one, and when you take the appropriate troubleshooting steps, you'll finally your problems solved more quickly
2. What is the difference between Scope and Context in JavaScript?: So the next question we need to answer is what is the difference between scope and context in JavaScript? Well, scope is the visibility of variables, and context is the object to which a method belongs. So if you put them side by side, we could think about it this way. Scope is a visibility variables, and you might ask yourself, You know, what is this scope of a variable? Or how is it variable, scoped and with context, which is the object to which the method belongs? From Time to time, you might ask yourself, What is this or what context is this method executed in? So when you think of scope, think of variables. And when you think of context, think methods. Let's look at an example, just let's start out with kind of a pseudo code approach. I got these three things on the screen. I've got Sam once or three and function, and these are just three things, and right now they're just kind of floating out in space, and I have no way to get a hold of them. So Sam is a string, and 123 is a number, and dysfunction is a function. Now let's just pretend that this function is a function, because it's really not correct. JavaScript syntax. But again, it's just pseudo code. For now, it's just pretend that's a function. Okay, so I've got to string this number and dysfunction, but I really have no way of getting ahold of these things. I can't get my hands on them. They're just there. I needed a way to refer to them, so we need to. We need to refer to these values in a way by giving them some kind of name. So let's call Sam name. Let's call 123 count and was called The Function Greet. So by doing that, I now have a way to refer to each one of these things. So when I leverage scope, I can create variables for each one of these things I can save. Our name equals Sam Var Count equals 123 and bar Greek equals function. And if I was going toe leverage context, I could create an object. Let's just say the objects called O B J and I could give that object properties because objects have properties and I could give it a name property that Sam and I could give it. Account property. That's 123 And I could give it a Greek property. That's dysfunction. Or I could mix it up Leverage, scope and contact so I could save our name equals Sam and O B j dot counting goes 123 and four. Greek equals function. So let's see how this actually works in JavaScript code. So getting back to scope if I wanted to create variables for these things I'd used of our keyword and I save our name equals Sam Farr Count equals 123 and our great equals function and inside of the Greek function Isler than name values. So I'm creating handles for these values by creating variables. Now, if I wanted to leverage context, I could create a no b J variable. It's an object. And then I give that object property. So B j dot name is Sam and O. P. J dot count is 123 and over. Jadot greed is a function on high alert. This stock name which would alert Sam. Now we're going to talk a little more in depth about what the this keyword means. But just right now. Just keep in mind that when it comes to context, the this keyword is really important and that this key were refers to the object which a method belongs. Now. If I was going to kind of mix it up and use scope and context, I could say open Jason. A variable and name is a variable, but over jade account is a property and then nobody dot greet is also a property. It's also a method when objects property is a method are, ah function, and then it's called the methods. Objects have properties, but when a property is a function, it's a method. In this case, it alerts the name variable self kind of three ways toe really two ways to look at it. You can leverage scope and create variables. You can leverage context and create object properties, or you could certainly mix and match. So once again, scope is the visibility of variables. And when you think of scope, think variables and context is the object to which a method belongs, and when you think of contacts, think methods
3. Required Software: there are some assumptions that I'm making about you. I assume that you already have knowed an NPM installed on your machine that you have a decent text editor and then you have a Web browser. If you do not have all three of these things set up on your computer already, you it's important that you stop now and take care of that before continuing on with the course. Now, if you need to install no, you can simply go to know J s dot organ Donald installer for your operating system. I do recommend, however, that you use a package manager to install node. This ensures that you can install the most recent version of noted in P. M. And then in future, you can update your version of note. If you're using a Mac, you can use homebrew, which I recommend, And if you're using windows, you can use chocolatey or scoop. If you need a text editor, I recommend Visual studio Code, which works on both of Mac and Windows or sublime text, which is also an excellent text editor that works on Mac and Windows as well. If you need a Web browser, I highly recommend Google Chrome or Mozilla Firefox, both of which work on Mac OS and Windows
4. Get Set Up: Okay, let's get the example code set up on your machine. We're going to do three things. First, will download the example code. Next will set up the project using NPM, and then after that, I'll demonstrate the local Web server. So first, let's start by downloading the example code. Just as a preview, I'm going to walk you through the steps of clicking this link in the class Web page, which will start the download of the ZIP file. And then, after you have downloaded that zip file, you're going to unzip that file. Open up that folder in your terminal application. You'll run NPM install to install dependencies. Then you'll run NPM. Start to start the local Web server, and you point your browser to local host 3000. At that point, you'll see the example Web page of the local Web server in your browsers. Let's actually walk through those steps together right now. Scroll down towards the bottom of the page and click your project. On the right side, you'll see a link named Scope versus Contact examples dot sip. Click that link to start the download, move into the fold that has the downloaded zip file. I've got mine on my desktop just to keep things simple. Unzip that file. Open up your terminal application and move into that folder. Next run the Command NPM install. This will download all the dependencies for the project. When that's finished, we'll need to start the Web server. So when you're NPM stoles complete, run the command MPM start. You'll see a message stating that the Web servers running on local host Port 3000. So open up your browser and point your browser to local host 3000 and you'll see the example. Web page. OK, now that you've got the example code set upon your machine, I'm going to walk through this little Web page that, put together, which will use as, ah for our discussions of the different concepts in this class and some of the code examples. This is a very, very simple little Web page I put together doesn't do much, but it's mainly we're gonna be using it to demonstrate the code examples in many of the lessons. So first in the upper left hand corner, if you click the show examples, but you'll see that there are links to all of the examples from the course, and it allows you to run the code examples without having a copy and paste. You can just run him right there from the browser. So if you scroll down and click the one that says method chaining, we're not gonna actually go into that right now. But, um, that particular example actually makes all of the code work for the U. I. So now I just want to show you how the page works. This is a fictitious sales team of 10 people, and for each sales person, I can click the select button and I can click the de select button. So when I click select that you can see the sales person has selected the you I changes a little bit and Aiken de Select it. And I can also just manually delete each sales person from the page by clicking the delete button and for that sales person. And when I select one or more salespeople, the delete selected button in the upper right hand corner shows and when I click that any sales person that selected is then deleted, So if I select, say, tomb or and click delete selected those to delete. And as you delete salespeople, the count, the total count of salespeople goes down. Ah, really simple stuff. But you know will be kind of walking through some code examples and were using this to base our examples off. And in any given time, if you want to reload the page, just click the reload page button and you can start from scratch. If you open up, your jobs could console. You'll also see a message whenever you load a code example that just tells you exactly which file was loaded. So you can be sure that, for example, I'm loading global scope examples two. And I see that in the console, so just let you know that you're running the right example in case you're not really sure.
5. Where to find the example code: For much of this class you'll be following along with the example code. So let's just take a quick second to find out where. To find these examples. Open up your text editor. I'm using visual studio code and move into the Project folder. Open the W W W folder. Open the Js folder, Open the Examples folder in the Examples folder. You'll find a number of sub folders and each sub folder of the example files for that particular subject. For example, in the Global Scope folder will find the examples for global scope and in the private school folder will find examples for private scope and so forth. We'll dig into these specifically a little bit later, but I just wanted to show you where to find the example code.
6. Scope Details - Three Kinds of Scope: But let's talk about scope in a little more detail, as we discussed earlier. Scope is the visibility of variables, and there's three kinds of scope. There's global scope, there's private scope, and there's block level scope.
7. Global Scope - Discussion: let's circle back and talk a little bit more specifically about global scope. Global scope is also known as the window object or outermost scope or a top level scope. Basically, global scope is any code that is not in a function. So, for example, I've got some code here on the left. And as you can see, I've got a couple of variables at the top, and I've got two functions food and bar and then at the bottom of the could execute those functions. So the variables speed and greeting and the functions flu and bar and the execution of those functions are global code. They are defined in the global scope, and that's because they're not defined in a function. So the code that's inside of the food and bar functions is not global code because that code is defined inside of a function. So in this case, I've got a variable called app, and this app is a private variable because it's defined inside of a function. So it's really important to remember that global scope is any code that is not defined in ah function
8. Global Scope - Demonstration: open the Examples folder and then open the global Scope sub folder. Now let's look at Big's example. Global Scope one. Here I have a global variable cold speed. I know that's global because it's not in a function is to find outside of a function. So I declare the the variable speed, which is equal 25 I have a console log statement out putting that variable and we should get 25 in the console. So if I click show examples and then global scope example one, we can see we get Global Street 25. Not a big surprise. So let's look at global scope number two. So once again I have the global variable speed which is equal 25. But then I have this function inside of the function. I also output in the console speed from food, which is the global speed variable defined online three and then online. Nine. I have the console log stated more output, the value of the global variable and online 10 Execute fu, which also outputs the global variable. So let's take a look at show examples global scope to, and I see the two messages speed from global scope. 25 speed from food 25. Pretty simple stuff. But the point here is that a global variable is wonders to find in the global scope, and we know we're in global scope. If we're not in a function. Variable speed is not defined in a function, which means it's global, even though we access it in the function online. Six. This speed variable right here is still referencing the global speed, and then we're out putting it here. So just remember that global variable is one that is defined outside of a function.
9. Private Scope - Discussion: and next up is private scope. Private scope is also known as local scope or function scope. Private scope is achieved by using the VAR keyword inside of a function. So if example in this function I create a variable called Speed and it's private because I used of our keyword, it's that simple. If I used of our keyword inside of a function that variable that I'm creating becomes private to that function. Now, it's important to point out something very, very critical about JavaScript, and that's lexical scope. The lexical scope is the way that scope behaves in JavaScript in that inter functions can see out. But outer functions cannot see in. And what I mean specifically is in this case, we have three functions outer, middle and inner, and the inter function, which is the enormous function, is nested. It's nested twice. It's nested inside middle and middles nested inside out. So from the inner function that function has access to the bar and food variables. Because the inter function can see out, it can see any variables declared outside of itself. So the inter function has quite a bit of access. It has access to its own private baths. Variable. It has access to the bar variable, and it has access to the food variable. But the opposite is not true, so the outer and middle functions are not able to see in, So the outer function has access to its own private food variable. But it cannot see inside the middle function that cannot see the bar variable, and it cannot see the bass variable because it's inside of the inter function. So once again, functions can see out, but they cannot see in. And that's lexical scope in JavaScript. And it's really important to understand that because it's the way that scope behaves and JavaScript, and when you declare a variable using Navarre keyword, that variable becomes private to that function, and nothing outside of that function has access to that variable. But that function can see any variables defined outside of itself.
10. Private Scope - Demonstration: open your Examples folder and then open the private Scope sub folder. Let's look at private scope one. This is pretty much what we had in the last global example. We have a global variable cold speed when we have this function called food, but we're accessing the global speed inside that function. So he wound up with 25 are console twice. Let's go to show examples Private Scope one and we want up with 25 in the Consul twice. Okay, so when you go to private scope to you'll see that things were a little bit different. I have my global speed here, but then, inside of this function, I have a private variable, and a private variable is created by using the var keyword inside of a function. So when we use the var keyword to define variable inside of a function that variable becomes private of that function. So this version of speed is not available outside of this function. You want to execute line number eight? I get the private version of speed this speed here in line number eight, references this speed online number six. Where is this speed online number 11 references the global speed online number three. So I should get in my console. The global speed is 25 then I should say the load. The local speed is 100. And let's show examples private scope to. And it's exactly that. Global speeds. 25 private spears 100. So the point here is that now, or have it, we're creating a private variable it also known as a local variable. But using the var keyword, let's look at private scope. Three. So here I have an example of of lexical scope. So with lexical scope, functions can see out, but not in so here. In line number eight dysfunction bar I access to speed variable. But this speed variable resolves to this speed. So when I see this console log statement online number nine, it's going to say bar 100. And that's because this function bar can see outside of itself. It can see that the variable speed that first variable speed of fines equal to 100 So here bars executed and this consul lock statement finds the version of speed it's equal to 100. Also, I output a consul log online 13 referencing speed. It also ones up with the version of speed equals 100 because again, inside of this function, speed is equal to 100. This function can see out outside of itself, and its console log statement is inside of the scope of food. So both the bar food Council log statements will output 100. And then this console lock statement will output 25 because here speed resolves to 25 the global version of speed. Those look at example, number three for private scope. Then we see Global 25 bar 104 100. So if we look at the last private scope example, it's a little bit different, because here inside the bar function, we're declaring a private variable speed. So online. 11 this speed resolves to this speed, which is 500. So Bar now has its own private version of speed, which means that this version of speedy reference on life 15 is going to be 100 because we're accessing the first in sense of speed. We confined in food and the private version of speed and food is equal to 100. But in bar the private version of speed is equal to 500. And that's because we used of our keyword to define speed, which creates a private version of speed. So now we should have, uh, here Global 25. When we execute food, we're gonna one up with Bar 500 Full 100. So let's look at show examples, private scope. Example. Four. That's what we get. We get global 25 Bar 500 food 100. So the main thing here that I just want to kind of point out is that tool. Two things. One when we used of our keyword, we create a private variable. It's private or local toe that function, and also that functions can see outside of themselves. That's cold lexical scope. So this bar function. If we were to take away the var keyword, take away this line, this would output 100 instead of 500 because it would, we would say, Hey, I don't have a private variable cold speed. Let me see if I can find one, and it would look outside of itself and it would look to this scope and find this version of speed. But here since we declared private variable called speed. This speed resolves to 500 the speed resolves to 100 in this resolves to 25 because with lexical scope, functions can see out. But they cannot see in. And once again, the VAR keyword creates a private or local variable just for the function in which it was defined.
11. Block Scope - Discussion: The final kind of scope in JavaScript is block scope, so block scope is achieved by using the let or const keywords inside of a block. Now it was introduced in the Atmos Script 2015 version of Java script. So before ec rescript 2015 we had two kinds of scope, global and private. And then after ec rescript 2015 was rolled out, we have three kinds of scope global, private and block level scope. So you may be asking yourself what is a black Well, this is a block block is opening and closing curly braces. And inside of those curly braces you put your coat and he code you put inside of those curly braces, um is block level coat. So, for example, I have this variable. I and I have declared it by using the let keyword both. So, by using the let keyword inside of a block, I becomes scoped to that block. Now, I could also have another I variable that's defined in this case globally because once again, if any code that's not defined in a function is defined globally, So here I've got this global variable called I And then I've got this other variable called I that's equal to 50 inside of the block. And these two can coexist very happily because the 1st 1 is globally scoped and the 2nd 1 is block scoped. So I could also use the constant you were to create that second I variable the differences . If I used the let keyword, I could turn around over it that variable the next line of code tickets. They let I equal 50. And then I could say, Let I equal 5000. No problem. But when I use a con ski word, that's a constant. So once I do that, I cannot try to change. I I is I. So if I say constant Article 50 and then say comes, I equals 5000 I'll get an error because I can't override eyes. So the different team let and Const. Is they both create block level variables or block scope. But, const. When you use that keyword, you cannot override it. So once again, there's three different ways now to create a variable. There is var, which creates private scope. There's let which creates, ah, block level or a block scoped variable, and there's the Const keyword, which also creates a block scope variable. But that value assignment cannot be changed
12. Block Scope - Demonstration: open your Examples folder and then open the block scope sub folder. Let's look at blocks, Hope example. One. You hear about this global variable I, which is equal to 100 then I've got a block of code here and it said The block I output the value of I and then on side of the block I put out Put the value by again. Let's look at block example Number one. So I see 100 twice for A and B, and that makes sense because I'm not actually doing anything to special here. I'm just out putting the value of I twice once once in the block of once outside of the block of my point here. Is that because I didn't do anything special inside the Plock? I is still 100 so it's look at black example Number two. I've got a global variable called I, which is equal to 100. But then inside of my block, I've got a block level scope variable I, which is equal to 50 and output that in the console. So this version of I is different than this version of I because this one is has block level scope. It's actually scope just to this block, so I equals 50 in the block. But I was 100 outside of the block. So when I look at block scope example to I get 50 and 100. So the main point here's were using the let keyword to create a block level scope variable , which does not conflict with the global one because it's scoped here to the block was looking block scope. Example. Three. So here I do pretty much the exact same thing. But instead of using the let keyword, I use the constant keyword to create this block. Scoped variable I So if I execute blocks? Example. Three Same thing. 15 100 open block scope. Example. Number four. So here are two global variables i NJ I starts it zero n. J. Started 100. I have a for loop and in the four loop increment I. But I also increments J. So what we should wind up with is loop where the council outputs are equal to zero and 101 101 202 and so forth. Let's take a look at block scope example for and that's what we wind up with. So the point I'm making here is that we're not leveraging block scope here. We're implementing I NJ inside of the blacklist. Let's see if we can fix that example. Five. What we do is it's very similar, except that inside of our block, we set J to be scoped just in his block. So now J is equal to 50 and we increment chase. What we're gonna wind up with is a loop where the council outputs are 0 51 1 51 to 51 3 51 and so forth because on every iteration loop were setting a new variable that scoped just to this block and increment in it just one. So if we go two blocks go example five. That's what we get. 0 51 1 51 to 51. Um, just illustrating that Jay is scoped to this block and every on every interational lock. We get a new version of J. We're creating a new version of J using the let keyword and it's scoped just to this block , whereas I is scoped globally. So it changed on every iteration, also get block scope. Example. Six. Here we're doing the exact same thing. Onley were defining J with the constant keyword instead of the let keyword. But this will be a problem because with the consequent word, we can't overwrite the value that we create once we create J and say is equal to a we can't turn around say J is equal to be because with the constant keyword, we're creating a constant. So this attempt to increment j will throw a type Er uh, look, at example Number six block scope Example number six. You can see on court type error assignment toe a constant variable. It's what that saying is, Hey, you created a constant here and then he turned around tried to change it. We can't do that. So the Const keyword works the same way as let keyword. It creates a block level scoped variable. But once you create that variably can't change, you can't override it. If you look a block scope examples seven. We do pretty much same thing, but we don't try to change Jay. We just leave it the way it is. So we'll get the council output of 0 51 52 53 15 So forth. So then a show. Examples block scope. Seven. That's exactly what we get. 0 51 52 50 And that's because we create the block level J variable, which is equal to 50. And that's fine. It's now. Jay does not conflict conflict with this version of James Global, but we just don't change it. So the thing to remember about letting Const. Is that with lead, you can create a variable that has blocked level scope and you could change it, whereas with Const. You can't change it. Once you created, you must leave it alone. It's a constant, but both let and cons create block level scoped variables.
13. Context - Discussion: Earlier in this class, we asked the very important question. What is context in JavaScript? And we found the answer was, context is the object to which a method belongs. That discussion was fairly high levels. Let's dig in a little bit deeper. Here. I have this object called account, and it has two properties account number, which is a number and get account number, which is a function in JavaScript when a property is a function. It's also called a method that happens to be true for a number of languages. But here to get account number. Property is a method because it's a function, and that function returns the value of the account number property of this object So in this case, would return 12345 Now we could have just said in our get account number, method return account dot account number, but that's not very elegant. So what we do is we say, return this start account number now since get account number is a method the JavaScript. This keyword inside of that method refers to the object to which that method belongs, and that method belongs to the account object. So the get account number method returns the account number property of whatever object it belongs to, which happens to be the account object. So when we say this stuff account number, we're really seeing account dot account number. So it's just really important to remember that when it comes to context, the JavaScript this keyword refers to the object to which a method belongs. I was digging a little bit deeper and look at some actual code examples.
14. Context - Demonstration: in your Examples folder, Open up the context sub folder and let's look at the context. Basic example. Here we have two objects full and bar. Each one of these objects has two properties. A greeting property and a Greek property. Now with objects. When a property happens to be a function, it's called a method. So each one of these objects has a greet method, so the food dot greed or the Greek method of food returns this stock greening. Now, in a method that this keyword is very important, it refers to the function the object to which a method belongs so that this key were in line. Number five refers to food because this method greet belongs to this object food. So once again, the job script. This keyword inside of a method refers to the object to which that method belongs online. Number five. This got dot greening resolves to food are creating online number 13. This stock greeting resolves to Bardach reading, so our consul log outputs should equal. I am full and I am bar because recalling food, artery and bar degree. So let's see this in action. If I open up block scope context place. Example. I see I am full and I am bar, and that's exactly what we expect. Now there's something we could do that might make this a little bit clearer inside of the Barda greet method. I'm going to put a council dura statements. I'm going to say council during this, I'm gonna just inspect this so we could just get a maybe a little bit deeper understanding of what this means online number 13. So now whenever we run the code, I see this object in my console and I could see it's got two properties creep, which is a function and greeting. I am bar if I do. If I take this and move it inside of food, food are greedy, greedy. Don't I rerun? This code now is object. You can see it's got a Greek method and a greeting. I am food. So the thing to remember about context is that it is the object to which a method belongs so inside of a method. The Java script. This key word can be used to reference the object to which that method belongs here, inside of food, that this keyword references full here inside of bar that this keyword references there. So this stock greeting resolves to Bardot greeting and this stock greeting online. Five Resolves to food are greeting.
15. When They "feel" the Same - Discussion: sometimes scoping context may feel like the same thing. So you may ask yourself, are scoping context Everth same thing? And the answer is no. Except there are times when scoping context may feel like the same thing. Let's talk about implied Global's and implied Global is something that happens when you omit the VAR keyword. So, for example, on the left side I'm creating this function cold food, and I create a speed variable by saying, var speed equals five. So when I do that speed is in the private scope of the food function. Speed is now a private variable on the right. I'm creating the food function again, but I'm just saying speed equals five. I omitted the VAR keyword well by omitting the var. Keyword speed is now a global variable because of our keyword was omitted. In fact, not only is speed a global variable, it's what's called an implied global. We're implicitly creating a global variable by omitting the var keyword. In addition to that speed is now property of the window object. That's right. When you create a global variable either implicitly or explicitly, you create a property on the window object, so by saying speed equals five inside of a function. I'm also saying window dot speed equals five. They both accomplished the exact same thing. In fact, I can also save our speed equals five in the global scope, and it accomplishes the exact same thing. In fact, I can even say speed equals five in the global scope and that accomplishes the exact same thing. So it's super important to know that what we're doing on the right by saying speed equals five When we omit the var keyword we're doing, two things were creating an implied global. We're creating a global variable cold speed, and we're also creating a property on the window object called speed because any variable that is global also becomes a property off the window object. And this is an example of one. Scope and context start to feel like the same thing because we're we're creating variables that scope. But we're working with an object or giving an object properties. And if we way would create a function or method called window get speed, we could say return this dot speed and it would work. So it's getting into this fuzzy area where scoping context will not being the same thing can sometimes feel like the same thing, and it's important to understand that they are not. But we're getting into a gray, a gray area where it does feel a little bit confusing. Now. If I were to put the VAR keyword back in this function and save our speed equals five speed is now back in the private scope of the full function again. And it is. There's no longer a global variable called speed and Speed is no longer a property of the window object. Now let's talk about the JavaScript, this keyword inside of global functions. So heavy disclaimer here for the next couple of minutes. We're talking about JavaScript in the browser. There's other context, such as Node, but for now, we're just talking about JavaScript as it runs in the browser. And also there's something called strict mode, which could dramatically change the conversation we're about toe have so just be aware of this, Um will definitely learn more about strict mode in a couple of minutes. We look at the code examples, but just for the next minute of to try to forget about strict mode and just keep in mind that we're talking about jobs. Get running in the browser. Okay. End of disclaimer. Now, this inside of global function. So inside of a global function, the javascript of the this keyword is equal to the window object. So on the right side, um created this function called food, and I referenced this. And when I referenced this, I'm really referencing window inside of a global function. The JavaScript. This keyword will always reference the window object. So if I say this dot speed, it's like saying window dot speed. If I say this start speed equals five, I'm really saying window dot speed equals five. And not only that, I'm also creating a global variable because saying we no doubt speed equals five is like saying in the global scope of our speed equals five or speed equals five. This is one of those situations where the lines between scope and context get a little blurry and it can be confusing. They're not the exact same thing, but they come very close in this situation. So just keep in mind that in a globally declared function or defined function, the JavaScript, this keyword references the window object, and you're essentially also creating. When you add a property to the window object, you're so creating a global variable. I think this will make a little more sense when we look at some code examples, so let's look at some code.
16. When They "feel" the Same - Code - Part 1: in your Examples folder, Open up the sub folder titled Scope and Context seem the same. And let's look at the first example file. Copy this example A code the one that's named create a speed variable and show in the console. Copy that code and paste it in your jobs. Good counsel. And we see that the output we get is 100. Okay, let's circle back. So in this example, we're creating a private variable, cold speed inside of this function food without putting in the console and only execute food. We see 100. So nothing special there. But just Teoh established that we want to use the var keyword to create a private variable . And we've talked about this a number of times in this class. So when you go down to example, be the one that's ah, that says what happens if you forget the var keyword here online? 15. I forget the var keyword I on line four of used var, but online 15 I just I omitted it, So I'm saying speed equals 100 I output speed and execute food. So uh, okay, So what happens if we forget the bar keyword, but I'm gonna copy this code, and I'm gonna paste this in the consoles free first page and I get 100 again. So we still get 100. We know that, uh, we created the variable. We output it, but I'm thinking something different happen here. Well, something did happen here. There's something that happens to that speed variable. What happens is the speed variable becomes what's called an implied global and implied global is a variable in browser based JavaScript, where when you omit of our keyword that variable becomes a property off the window object, it becomes a global variable. And remember, it's really super important piece of information is that a global variable is a property of the window objects. So if I type speed in my console, I see 100. In fact, if I type window got speed, I get 100. In fact, if I type window and I inspect the window object and I scroll all the way down and I look, I could see there's a speed properly right here. So the point here is that when you omit the var keyword, you create what's called an implied global. It becomes a global variable, and you've done that implicitly so. Creating a plot AMP implied Global is really the same thing as declaring the mobile the variable global. So Lines 14 and Line 17 are exactly the same. They do the exact same thing. They both create a global very well. The only difference is online. 14. I'm doing it explicitly. I'm saying var speed equals 100 I'm doing it in the global scope was online 17. I'm doing it implicitly, and I'm saying, Well, speed, it was 100. And because I'm in a function the omission of the var keywords says, Oh, it's going to be a global. But the other thing that happened is we discovered a few seconds ago is that creating and a global variable also creates a property of the window object with the same name, so lines 14 and 15 are exactly the same. They accomplish the exact same thing. Var speed equals 100 window dot speed ah equals 100. Both create a global variable that's also a property of the window objects. So this isn't a situation where scope and context almost kind of merged. They very much feel like the same thing, and in a way you can almost think of them as the same thing. It's depends on how you want to debate it, but it's really the to kind of meet, and they certainly feel the same because we have a global variable was no doubt about it. But that very well becomes a property of the window object. And you can also say that this is the exact same thing. Line 16 does the exact same thing as lines 14 or 15 because by leaving out the far keyword on 16 I'm creating an implied global. I'm just doing it in the global space. So all three of these things accomplished the exact same thing. They create a global variable, and that global variable becomes the property of the window object at incredibly important piece for information to keep in mind, because when you're working with browser based JavaScript, the window object is a very important object. Global variables are an important concept to be aware of their usually bad. There's plenty of, um, there's definitely plenty of problem properties of the window object, but creating global variables intentionally is usually something you want to avoid. But it's important to understand that when you omit the var keyword inside of a function, you create what's called an implied global. It's a global variable, you're doing it implicitly, and that variable also becomes a property of the window object. Any global variable is also a property of the window object.
17. When They "feel" the Same - Code - Part 2: Now let's look at example. See the one that says, What is this? So I've got this function food again. And inside of food, I create a variable. So this is good. I'm using the var keyword again, which I think is better. So I'm creating a private variable inside of food. So speed is private to this function, and I alert this stott speed, okay? And then I execute food, so we should get an alert. But the question is, what will be the value that we see in the alert? That's the question. So let's try. It's copy this code and go to job script. Consul, pace that coat in. And when you execute the code, we see undefined to the alerts. This dot speed is undefined. All right, let's see if we can figure out what's going on. Well, once again, we have this private variable speed and we alert this start speed. Well, when I see something, that's something I think, object dot property. So this dot speed is not the same thing as speed because if he wanted speed, we would just get speed. But we don't get speed, we get undefined, and we're not alerting speed. We're learning this dot speed. So as we've talked about many times in his class, that job script this keyword refers to the object to which a method belongs. Well, this food function isn't really, um, a method. Or is it? Maybe it iss Let's copy this code again and let's execute the code. And then let's see what happens if we type Foo, huh? So I just typed fu in my console. I get looks like the code from our function. It looks exactly the same as the code from our function. Well, turns out that, and if I type window dot food, I get the code from our function. So it turns out that Fu is a property of the window object. And the reason is because we're declaring food in the global scope right here were in the global scope, were not inside of a function where we're inside of a function here on lines 26 or 28. But the actual function declaration of full online 25 is in the global scope. So when we create a global function, we're creating a global variable. And as we discussed a few minutes ago, a global variable is also a property of the window objects. So right now food is a property of the window object. Okay, so that means that the this keyword refers to the window object. So when I say this dot speed, I'm asking for the speed property of the window objects. So alert this starts speed will be the exact same thing as saying alert window dot speed lines 28 29 are exactly the same thing. Exact same thing. So the situation is we don't have ah, speed property on window Not in this example. The previous example we did. But here we don't because this speed is private right there. Online 26. That's a private speed, but window dot speed doesn't exist. And if I were to come up here and say var speed eagles, let's say 5000. So copy this code and refresh the page and I'm gonna pace that code in. And now I see 5000. How I see 5000 with the reason is because now we create a global variable called speed. This dot speed equals this dot is window dot speed So window does speed the global speed is 5000. So in this case, we get a value, which is which is good. But the original question did not involve a global speed variable. So in this case, online 28 this start speed or window dot speed is undefined. We never defined a window dot speed. And that means the alert on 28 produces undefined. There is no window dot speed property.
18. When They "feel" the Same - Code - Part 3: now take a look. At example D uh, where it says, What is this in strict mode? So in this situation, I'm doing something your online 36 from saying use strict. And that basically says to the JavaScript engine for the execution of this function, use strict mode. And the difference here is that while this function executes, we're gonna be in strict mode so that the think the behavior you'll see is different in the consul. Copy this code. It's pasted in your console, and we get cannot re property speed of undefined. So speed among the fine. That means the object that we're trying to get a speed property from is undefined. So this that speed it's not that this dot Speedos under find is that this is undefined. And the reason is because when wearing strict mood and browser based JavaScript when we're in strict mode, we can't access the window object using this, um, from a global function, it's just a one of the characteristics of strict mode. So I'm gonna continue out of strict mode. But I just wanted to point out that it's important to know that when you're using strict mode, you cannot access the window object using this inside of a global function
19. When They "feel" the Same - Code - Part 4: Okay, let's look at example E. The one that's titled Food was now a constructor. So online 49. I have the full function, but you may notice that I have used the capital F when I named Food, not just lower case F Oh, but Capitol Foo. Now that doesn't essentially change anything, but it's a convention that most programmers use, that you want to capitalize the first letter of a function when you want it to be a constructor. And I do want to be constructed because online 56 I'm not just executing food. I minced ain sheeting it. I'm saying Barbu equals new food. And if you've worked with construction funk constructor functions at all job script, you know that when you instead she ate a constructor, you do executed so fu will be executed. But it's a little bit different because bar the value bar ones of being the instance of the food class. Food was essentially acting as a class here, and bar is going to get an instance of the class. So inside of our constructor, I create a speed variable to private to that constructor, and I alert this dot speed so let's execute this code in our console and we'll see what what happens. So I alerted, and I get undefined. Why is that? Well, if you go back to the code, will, my first thought might have been that well, I create this speed variable. So when I'm in Stan, she eating food? Shouldn't the execution of food producer an instance of food? Will it should. But the problem is that you may think that the word this references, um, the instance of food and it does. It's true food. The bar This equals bar, meaning that when you instead in shape for using bar the this keyword inside of the constructor preferences the instance that's being returned so that that's true. But speed is not a property of the constructor. It's a variable, and that's one of the areas where scoping context can feel like the same thing. But in this case, they're very much not the same thing. Speed is a variable when you think variables, you think scope, but in this case, we're we're trying to reference A. We're trying to reference the speed property of this variable, but of this instance, but the instance doesn't have a speed variable. It has a speed. Doesn't have a speed property as a speed variable. Eso this dot speed is essentially undefined. If I were to say, um let's see, uh, let's see return, um, Speed five 1000. And then I alert Bardot speed. It should work. So let's copy this code and paste it and we get 5000. The reason we get 5000 is because now the class food does have a spread property bar winds up with speed property. In fact, if I were to do ah, a console during I will, I just type bar in a in the console. I see I get an object with a speed property. So in that case, it would work. Now, the instance of food does have a speed property. Another way to do this would be if I wanted to keep the alert inside the constructor. I could say food dot pro prototype dot speed equals of, say, 10,000 just to prove our case here. So I'm gonna refresh the page and, uh, hopes I shouldn't say no. See, there you go. Type of. Okay, So let's refresh page. And now I get 10,000 And the reason is because even though I don't declare a speed property when I create the constructor, as soon as I create the constructor, I create a speed property on the prototype object. Now prototyping is again That's that's Ah, that's fuel for a whole nother class. But the point here is that I'm extending the food constructor here with I'm giving it a prototype are giving putting up speed property on its prototype object, which means that when I instead she ate. Foo Bar will have a speed property, so this dot speed does resolve to 10,000. So but the original question did not have a prototype, and it the reason why we got undefined is because this class or constructor has a speed variable but not a speed property.
20. When They "feel" the Same - Code - Part 5: now look, at example, if the one titled Food is just a function again. So ah Fu is just back to being a function. It's not a constructor. I don't stain. She ate it. And online 61 I alert speed equals 100 or I say speed equals 100. And then on 63 I alert this dot speed. So copy that code and refresh the page and paste that code in your browser and we get 100. So up until now, in a lot of these examples we've gotten on defined. But in this case we get 100. And the reason is if you remember that by omitting the var keyword, I wind up with an implied global. So once again, omitting the var keyword is pretty much the same thing as doing this, which is also the same exact thing as doing this, which is also the same exact thing as doing this line 60 61 62 or all the exact same thing . But regardless Online 63. By omitting the var keyword, I create an implied global and we create a property on the window object called speed, which means that Online 64. When we access this dot speed, we get six. We get sick, we get 100 because we're basically asking for window got speed. So this is a case once again where that the line between scoping contact context can feel fuzzy because we're creating a variable here in Line 62. There's no doubt about it, but we're creating an implied global and imply global's become properties of the window object in browser based JavaScript. So this is where its scope. But in a way it's also context because we're reaching for the property of an object, and we can access this inside of this function, um, and reference the window object.
21. When They "feel" the Same - Code - Part 6: in the scope in context seem the same sub folder. Open up the file scoping context seem the same to so as you've seen a number of times in the class here. We're iterating all of these sales people, and we're using the each each method on the each ally, and we're creating a reference to the particular ally or list item. So we're doing that by creating a variable called item, and that's equal to this. And as we know, this callback is executed in the context of the list item. So that kind of makes sense were using this wrap with Jake weary and we're setting an equal toe item. And then we're saying Item, find a select button and then we're setting up the click of an alert for click event handler for that select button. So if you look at the next file, scope and context seem the same. Three. We're accomplishing the same thing that we're doing it differently. Where getting a hold of this second argument that's passed to the callback function called Dom Element, and we're wrapping it with Jake weary sourcing item equals Dom Element Rapid Jake weary. So let's take a look at what Dom Element really is. So back in either Web page. Execute the example. Scope well, shooting when scoping context, feel the same. Three. Okay, so I get a bunch of console outputs, and there are only almost the same thing. But you can see its ally sales person zero ls sales person. One also is person to and so forth. So what's happening is in each one of those cases were out putting a dom element. So the point here is that this dom element that you see in the console represents each of the list items in each of the salespeople Dom elements, though iterating over. So this call back when you call it each message. The callback receives two arguments. First argument is index, which is the numerical index of the element, and the second argument is the element itself. So in this case, it's kind of it feels it's sort of where scoping context feel like the same thing in that we're creating a variable. But what we're setting the variable to is the current dom element over which were iterating , which really is more of a context thing because it's like when we use the word this earlier . It's the context of this method. Off this function is the dominant moment that we're iterating over, which is dom elements. So this is a situation where it's kind of scope in context in the same line online 10 item is definitely a variables that scope, but then we're setting equal to an object, which is the context of which or context on which this function is being executed. Now, if you look at the file scope in context in the same four, we're doing something a little bit different down here. If you look, let's look back at three again and look at how we, uh, executed the toggle classmethod. We said Sales person underscore Plus index will indexes a variable, so we're using scope here to get a hold of the current element. So sales person zero says person wants this person to on so forth. Um, but in example, number four we're just saying item were using the item method we used appear, which that's also variable. But in a way, it's like where scoping context kind of having that fuzzy line because we're we're setting the variable equal to the context on which this function is executed. So in a way we're kind of using scope and context here at the same time. It's a variable item is variable, but that item with variable item variable it's set to the context on which this function is being executed.
22. Making Better Decisions - Discussion: One of the key goals of this course was to be able to make better decisions about our code using our knowledge of scope and context. So in doing that, there's probably a couple of questions that might come to mind first. For example, when should I leverage scope and when should I leverage context? Well, before you can really answer those questions, we need to think about a more important question, which is? What is the problem you're trying to solve as you plan your code at any given moment? What is the issue run into, or what? What are you trying to achieve? And probably you're going to be trying to solve problems that relate to, You know, the kind of things we learn in these great books that we read anti patterns, things like repetitive code or hard coded values or bloated functions. These are just examples of the kinds of problems that we don't want to run into as you plan and our code. So at any given moment, once you're clear about that, the problem you're trying to solve, then you can go about answering this question, which is what is the right tool for this job. And of course, there are many different types of tools. There's tools for each job, but you need to figure out what the right tool is for the job you have at hand. And once you've chosen the right tool, then you can start planning out your code. And deciding shouldn't leverage scope. I should Leverett context for this particular problem. So let's take us a step further and actually look at some code examples to, ah, to really kind of understand what this means.
23. Making Better Decisions - Demonstration: in your Examples folder. Open up the planning sub folder and let's take a look at planning example one. So you have got some code that should look familiar to you. Um, iterating over the sales people, and I've set up a bunch of click event handlers. You'll notice. I'm saying that I've got some repeated coat. So let's do a search for the code that I'm saying is repeated to this two instances of it. So there are two places in my code here on line 27 line 47 where I want the length of all these selected salespeople. So what that means is that, um, if you go to run the example method chaining, that's just where the apple, the all the code is working. So when I, um, select salespeople when I go here and click the delete selected button that deletes all the own, all the salespeople who are selected and I know that because when I inspect any one of those particular allies, you can see it has the class selected. This one has a class selected, and if I would remove that class, he would no longer appear selected. So here was saying, Salespeople, Ally selected length the length of all those elements. So there's two cases where I want to know the length of the allies selected elements or how Maney allies selected elements there are. But the problem here is we've got repeated code. I'm literally typing in quotes, pound salespeople, space l I dot selected twice. And what happens if I change the sales person element? Salespeople I d Teoh you know, salespeople. All what say It's just, you know, I'm gonna for some reason changing the name of that I d sevens. I have to go to each one of these and I have to go like that, and that is messy business. We don't want to do stuff like that. It's extremely hard to manage. And there could be tens or hundreds of files in our code where that's or that the literal I d has been setting. We don't want that. So another way to approaches would be, too if you look at explaining example to we set a variable salespeople. So this variable dollar sign salespeople represents the live Dom Dom element. This element this variable right here represents this element right here. The idea of sales people. So now we have a reference to that element. So we don't have to constantly keep retyping this. And if we rename this this Ah, I d in our mark up to ah, you know, sales people hyphen all. Then we could just make that change here once and little cascade to our code. So that's working out better. Because now we're just saying dollar signs salespeople dot find l I selected. And same thing here that's a little bit more efficient, But we've still got some repeated code. Were still literally typing out l i dot selected and l I got selected. And what if we make those allies dibs? Or what if we change selected class to I am selected so that s'more retyping, um, I, um, selected and I've got to take that change and I'm gonna make it down here, and that's once again messy business. We don't want to do stuff like that. So I think there's a better way to do that. If we go to plant Example three. You can see that what we've done here is we've got our dollar sign. Very salespeople variable. And then we've got a method function called get salespeople length and that returns the length of all the selected salespeople. So we're saying stole sign salespeople dot find were using the find method of this object passing an ally. And ah, actually, this is getting all sales people don't length. So how many sales people there are? And then we want to find out the number of selected sales people there are. So we're saying salespeople dot find L. I got selected. So here it's just find l. A dot length. Here it's find l a dot selected length, but in both cases were executing a function in that way. When we want to know the number of sales people, we just call the function, get salespeople length, it's just that simple. And then we want to know the number of currently selected salespeople. We just call the function, get selected salespeople length. We do that twice, and that way, if anything changes in our code, if we change this idea to sales people, it doesn't matter. We make that change right there, and that's it. We don't worry about it. And if we were to change the, um, the the Allies that have the salespeople to dibs. We could make this change there, and we don't have to make it any place else. Or if we named. If we were named the that. If we renamed the class that indicate something is selected to I am selected, we just make this change here and that's it. Everybody just calling this function. They're not worrying about this. They're calling this function dysfunctions, taking care of how that set so you could re factor all day long. And we could really get rid of all these string little rules that we're using our co because we've got a whole bunch of them. And this is all again kind of messy business because this is thes air strings that we have to change my hand if any of these definitions change. So the main point I'm making here is that we want to. Now that we understand the difference in scope in context, we can do things like creating a variable scope that we can use throughout our code. Or we can do things like create leveraging methods on objects, context to re factor a code or planner code in a way that's smarter and easier to manage.
24. A Bit More About Context: Let's talk a bit more about context. I let the cover two things first, switching context and then second this versus this wrapped with Jake Weary.
25. Switching Context with .call() & .apply(): So let's find out what it means to switch context in JavaScript. Earlier, we learned that context refers to the object to which a method belongs, but sometimes we may want to make a method think it belongs to a different object. For example, when left side of the screen, I have an object hold food on the right side of the screen. I have an object called Bar. Each one of these objects has a greeting property, and each one of these objects also has a Greek property. Now once again and JavaScript when a property is a function, it's called a method. So in each case, the Greek method returns this stock greeting. So if I would execute food dot greed, I would get I am full. And if I were to get execute Bardot greet, I would get I am Bar, and in each case, the Greek method interacts directly with the greeting property of that object. Each greet method is executed in the context of its object. Food dot greed is executed in the context of food, and Bardot greet is executed in the context of bar Well, there's a way that weaken jump in and we can change the context of each method. It's called context switching, so we can make the food dot greet method. Think it belongs to bar and we could make the Bardot greet method. Think it belongs to food because you can see here Food agree, is now on the right. It has that blue box. And when execute food dot greed, I get I am borrow one. Execute Bardot greed. I get I am food. This may seem a little confusing, a little odd, so let's jump into some code and we can see how this really works. In your Examples folder. Open up the context of folder and then open the file context coal and apply to I've got two objects here, full and bar, and both objects have a greeting property, and both objects have a greet method in both cases agreement that returned the value of that objects greeting property. So if I would execute food dot Greek, I should get I am food. And if I would execute Bardot Greek, I should get I am bar. Let's make sure this works as we expect. So copy both of those objects. Payson, you JavaScript console and Now I'll execute food dot green and I get I am food. And if I execute, execute Bardot greed, I get I am bars. That's pretty much what we expect to happen down here in Line 17. Copy this code and execute this in your JavaScript console. So something pretty weird happened here. I executed food, Doc greet and I got I am Bar, which doesn't really make sense, but there's a little more going on here, I said. Food degree dot call bar. What's happening is I'm using the call method to switch the context of the food doc. Great method. So the sin taxes. It's object dot method dot call new context. So food Dockery call, but do it in the exit in the context of bar. And if I would say bar Dockery dot call, uh, food I would get. I am food. I'm executing Bardot Greek, but I'm getting on food because I'm saying Bardot agree. Call in the context of food so it happens with the call method is you temporarily take a method and move it into the context of another object. It's not literally what's happening, but it's effectively what's happening. So when I say food food agreed A call bar executing this method. But I'm making it. Think it belongs to this object. And when I'm saying Bardot Greek call foo I'm executing bar degree, but I'm making it. Think it belongs to food just for the moment. So if you copy this line 20 here, it's actually line 18. If I reopened this file So line 18 and I run that I get the same thing. If I execute food dot greet, apply and bar I get I am bar because I switched the context of food. Agree to bar now the call and apply method do the exact same thing. The only difference is passing arguments. Let's say that the food agreement that expected to arguments A and B and I want to pass those Well, if I wanted to do that with call, I would pass the arguments in a comma separated list. And if I wanted to do that with apply, I passed the arguments as an array. So with food agreed a call. I pass it the context of new contact. We just bar comma and then all my arguments and with food agreed that apply. I pass it bar and then an array of any arguments. But in both cases, the call and apply methods allow you to switch the context in which a method is executed.
26. Method Chaining - Discussion: So in JavaScript is a concept called method chaining. It's actually not specific the Java script. You'll find that this pattern in a number of languages, but it's something that's very good to be aware of, and it can also help you to write code that's a little bit more expressive. So on the left side of the page, I've got this object called APP, and this APP object has three methods and it start and set up. We don't really care what they do. Let's pretend they do something magical and amazing. But the main thing is that we have an object with three methods, and on the right side of the page, I execute those methods by saying app dot in it app dot start and app dot set up. So that all makes perfect sense. Seems like a pretty pretty good, solid way to go. But what if, in addition to the's funk, these methods doing whatever it is they do? What if they were all to return a very specific value? What if they all returned this? Well, we know that in JavaScript the deed this keyword refers to the object to which a method belongs So in each one of these cases on returning APP, unit method returns app, the start method returns AP and a set of method returns app. So that means on the right side I could change the way I'm writing my code. I could do something like this where I say app dot in it dot start dot set up. And the reason that works is because each time I execute one of these methods, it's returning app which allows me to directly execute another method on that object. So when I say apt out in it, that directly returns out, which allows me to say dot start and then the start method returns app which allows me to say dot set up So another way to look at this would be Think about the direct connection between this and app. You know, in the unit method, I'm returning this, which means I'm returning app which allows me to directly call the start method. And then when I called a start method, I'm returning this, which allows me to call the set up method, and that allows me to I could even maybe Shane another method on here and created a method cold food and then, um, ethical bar and I'm ethical Topaz and just I could change all day. But this pattern, if you look at the code on the right, looks quite a bit different than saying apt out, innit? App dot start app that set up the code maybe a little bit more expressive. And if you're really creative, you can write code that maybe even be easier to manage. So if not mandatory, that you do method training. It's simply a pattern that's good to be aware of, and it could be very helpful a time. So let's see if we can get a better understanding of method chaining if we actually look at some code examples.
27. Method Chaining - Demonstration: in the Examples folder, Open up the context sub folder and to look at the file named Method Chaining. Now here I've got the entire application, but I've changed the code dramatically. Um, where's earlier? We just had Ah kind of Jaco Rico just laid out in a more a procedural manner. Here I have created an object called APP and then have created different methods called in it and Start and Dom set up and etcetera. So the code is much more object oriented. It's a little bit cleaner, easy to read user to manage, but I've done something down here that it's a pattern that I want to just discuss. For a couple of minutes. I'm doing something called Method Training, so I'm calling the Dom set up method. The bind, Reload page event handler method, the bind, the lead selected event handler method and the buying user items event Taylor's method. But in each case, I'm not saying app dot that method like you would expect. I'm just saying app dot app dot dom set up dot buying reloadable blah dot bond Believable, uh dot Bind. So I'm calling app, but then I'm just calling different methods on app. So how is it that I can skip using app dot app dot apt out every time? Well, let's take a look at each one of these methods. Let's look at the dom set up method down here. So Dom set up has an interesting line. It does a bunch of stuff that we're not really worried about right now, but it returns this And if we remember, what is the Java script? This keyword refer to refers to the object to which a method belongs and the Dom set up method belongs to the app. Objects of this method returns this or returns app. So when I execute this code here in London 21 here I wind up with app so I could just turn around and call the binds Reload Page event handler method. And then when that method executes buying reload page event handler, I returned this. So since executing that function returns app, I can turn around and called buying delete selected event handler and so forth. So if each method returns the app object, that means I can turn around and call another method on that object. This is called method chaining and it doesn't effectively change your code in terms of what your coat does. But it allows you to write code that may be easier to read and a little bit more expressive . Because if I someone else wrote this code and I inherited it, the first thing I would Seeiso this at Method has a number of this app. Object has a number of methods and I'm calling them all here. And all these methods returned the app object, that's for sure. There's no doubt in my mind because I know that you couldn't do this. You couldn't method Shane like this if these methods did not return the app, object and method chaining is really easy. It just you just need to return the object to which that method belongs from each one of the methods allowing you to chain methods off of a single reference to an object
28. "this" vs $(this): Let's take a moment to discuss the difference between this versus this Wrapped with Jay Query. Now, if you have no interest in Jake where you could feel free to skip this lecture, But I think most Front and Web developers I have worked with J Query to some extent and probably work with on a regular basis. It's definitely worth taking a minute to discuss the difference between these two sitting Rios and some of the problems that you can run into your Examples folder. Open up the Context sub folder and then open the file of context this versus this one. So here I'm iterating over each of the sales people don elements or the list items in a new generation of the each method. I'm creating a click event handler and in the click of an handler, I'm saying this dot hide. So let's first run the code and see what we get. So go to show examples and context. This rush is this one. So now I've run the code and click the select button and I get an error this dot Hide is not a function. All right, what's the problem? We'll see if we can figure it out. So the first thing I want to do is I want to disable or comment along number five. Since that's throwing an error, it's not really going to help us. And then I'll paste in to console dir statements. The 1st 1 is I'm inspecting the job script. This keyword in the 2nd 1 is I'm expecting the job script, this keyword wrapped with Jay Query. So let's save that file and then we'll just refresh the page and click the select button, and I guess you console their statements. Let's look at the 1st 1 The 1st 1 is a dom element. It's a raw JavaScript dom element, and the 2nd 1 is a dom element wrapped with Jake weary. So the difference is, the 2nd 1 is the 1st 1 wrapped with Jake Weary Hope that makes sense. But for the 1st 1 it let's scroll down a little bit and we can see there's a style property , and that style property has a display property on display. It's crowing, set to an empty string. Okay, so we're gonna talk about that in a second. So the short answer is this is the raw Dom element that's currently being iterated over that was in this case was clicked. Where is this Represents that dom element wrapped with Jake Weary. So it's, um it's like taking yourself and putting yourself in a coat. It's still you, but you're wrapped with a coat. Um, so let's look at the, um if you look at the file, contact this versus this to what I'm gonna do is say this dot styled that display equals none. So if you run context this versus this to and then click the select button, you can see the button disappears. And if I click other buttons, they just disappear. Why is that? Well, if you remember that we did the consul dot dir this We saw that this this jobs go keyword, which is a Dom element, has a style property and a style property has a display property, and we're just setting it to nuns. The point I'm making here is just to illustrate that the JavaScript this keyword inside of this click event handler is just a raw dom element. It's not has nothing to do with Jay Query. If we go to contact this versus this three uh, something a little bit different is we're saying this wrapped with Jake. Weary dot style dot display equals nuns Let's see how that works. So if we go to show code examples context, this versus is three and then we click the select button. We get an error cannot set property display of undefined. And that's because this rapper Jay Query does not have a style property. Remember, it's the JavaScript, this keyword or it's the raw dom element, but it's wrapped with J. Crew, so it has different properties and methods. If you open up context, this versus is four. The difference is now we're seeing this dot high. So if you run context, this Versace is four and then select the button. It disappears and there's no error. And that's because Jake Weary or this rapid Jake Weary, does have a hide method. So the main thing to keep in mind is that the JavaScript, this keyword by itself, inclined inside of a click event handler is just the raw, uh, javascript dom element. And it has a certain set of properties and methods. Where is this raft with Jay Query? That is a J query object and It's basically taking this object and wrapping it inside of J Query, which gives it different properties and methods. So you might be thinking, Well, I use a query and I use this rapper Jay Query, and it's fine. Well, there's some situations when Jake, we will return this. And you think it's going to be this rap with Jake weary like when you're creating a J coury plug in. There's some tricky scenarios, So 99.9% of the time, you'll be dealing with this draft with Jay Query, and that's all fine. But two things. One. It's really good to understand the difference and to it's going to come up. There's going to be a time when you think you're getting your one and you're getting the other or you want to convert one to the other, and that's all fine. But you can only go down that road if you really understand the tooth. The difference between these two things
29. A Bit More About Troubleshooting: earlier, we discussed the importance of understanding a different routine scope and context with regards to troubleshooting. So now that we have a really solid understanding of the difference between the two, let's apply that knowledge and some code examples and see how it can help us solve problems .
30. Troubleshooting a Scope Problem: in the Examples folder. Open up the troubleshooting sub folder and let's look a troubleshooting example one. So here I'm going to reiterate over all of these sales people list items, and I'm doing it in kind of am kind of an old school way and that I'm creating an eye variable and setting a reference to the sale. The list items on the list of salespeople dom elements by using the document a query selector all. It's not particularly fancy, but there's a reason why I'm doing it this way. So I created a four loop, which is again just kind of a really old school way of iterating something. And inside that four loop, I'm looking for the creator reference to the sales person. So I say var item equals sales person eyes. So first gonna be sales person zero sales person, one sales person to and so forth. And then I'm saying item, find that thes select buttons will find a select button for that item. And then I set up a click event handler for that item. So in the end of the user clicks that select button, I'm gonna use this Ah, fine variable as item variable to find the de select button and show it I'm gonna first hide the select button showed a dislike button. Toggle a selected class. So let's see how we make out here. I'm gonna go to show examples and go to troubleshooting example Number one. OK, so run that code. And then I clicked the first piece. First select button. So the diesel it's deletes like the button shows the selected the select button, and I clicked one away. But I'm not seeing the de select button for each list item, and it's not toggle ing. The selected class of the left side is not turning green as I expected, so if we zoom out a little bit, I want to show you something really odd. That's happening here. As I could watch what happens, I click each select button. The last list item is toggle ing. It's going green and the not green green, and they're not green. So for some reason, every time we click a select button e having a couple of problems, and the main problem is that we're not seeing the de select button for that item, and the last element in the list is toggle ing, which is not what we want. We want the I am that we're clicking to be Tongling. So it's sleeping. Figure out the problem. Well, the first question we need to ask yourself is, Is this a scope problem or a context problem? Always the most important question. So I'm thinking about things, and I'm thinking, Well, the funky thing that was happening was the last element in the list was toddling, but none of the other ones were, And I'm iterating over a list I'm using a variable that counts up. I started zero and goes up to the value of sales people that length or tells you without length minus one. So I'm thinking that well, if the last one If I is incremental and only the last element is toggle ing, then maybe there's a problem with I. And I's, um, is variable, that's for sure. So when I think variables, I think scope. So why don't we do this? Uh, let's put a console. Ah, council statement, Insider click event handler was going out. Put the value of I. So I'm thinking that on each click, I should show it if I click the very first element in list I should see you know I equals zero. If I click the second Element agency I equals one If I click the ninth element at U C, I equals nine and so forth because this quick event handler is referencing, You know, I we created this item object by referencing salespeople I So we definitely need to know that we're getting the correct value of I for each click. So let's refresh the page and see how we make out. So I'm gonna start clicking and when I click each put and I noticed that it just says I equals 10 Every time I equals 10 I'm thinking I should say I equals zero. I equals one. I equals two equals three. But just I equal 10. And it kind of lines up with what we're seeing, which is the last item in the list is toggle ing not the item were clicking with the last item in the list. So I'm thinking that I is not what we think it iss and it turns out that's correct, because what happens is even though where we're iterating over, I going from 0 to 9. The problem is that this click event handler could happen. You know, the adoration happens in, you know, microseconds but milliseconds, but the click of enhancing the user might click the button in a minute or 10 minutes or 10 hours. But that reference toe I does not eyes not cashed with each generation of this list. They all fire off, and when you start clicking the clicking the buttons, I is 10. So we need a way to protect I or create a scoped version of I. So if we go back to the page and run troubleshooting example Number two and start clicking around, I think you'll notice that everything works exactly as expected. If you click an element, the de select button shows and tacos green and the last element only behaves that way if you click it. So we're getting the behavior that we expected. The question is why? Well, the reason that happened is because if you look at troubleshoot example to what we did was we used an immediate invoked function expression or an immediate function here, and we we get this item, we pass it into the function, and then we have our code. So basically our code gets a privately scoped version off that item, and that's preserves that when the element the select button is actually clicked. We've got I zero I one I two or three now I don't want to get really too much into immediate functions and closures, because that's definitely stuff that we could have an entire class on. But the point I'm making here is that we asked ourselves the question. Is this a scope problem or a context problem? And through a little bit of logic, we determined it was a scope problem and that allowed us to quickly drill down and figure out where the problem was happening and how to solve it, even if we didn't have the answer of how to solve it right now, at least finding out what the problem is. It wasn't a context problem. It was a scope problem. And that's the thing that's really important in this case, was determining that for this example, this was a scope problem and it was solved by creating the properly scoped version of I or this item object that we wanted to pass into our click event handler
31. Troubleshooting a Context Problem: open the file troubleshooting Example. Three. So here I've created an object called App, and this APP object has two properties. The 1st 1 is a method called Show Delete selected and that just shows that delete selected ah button. And the second method is called salespeople Ally it aerator. And that's used as an iterated er for each sales person allies. So down here recalling the each method on salespeople. Ally. So this happens 10 times, and each time it happens, we're passing it app that salespeople it aerators. So this is going to be executed 10 times. And when it's executed each on each execution we're setting up. Ah, click event handler for that list items select button. So let's run example Number three and see how we make out so troubleshooting example Number three. OK, so we ran the code and then I'm gonna select one of the buttons and I get an error. Okay, so let's take a look at this error type er, this stopped. Showed the lead selected is not a function. Well, what's the first question we want to ask ourselves when we troubleshoot? We won't ask ourselves. Is it a scope problem? Or is it a context problem? And I got to say that whenever I see the JavaScript, this keyword in an error, I pretty much feel like it's a dead giveaway. It's it's it's very unlikely. It's not a context problem, because I see the word this. So no, it could be scope. But I'm going to go with context on this one because I see that this keyword So, um, as far as where to begin, I think I'll just copy this code. And then when I go to our code, I won't do is search for that exact piece of code and see where it takes us, and it takes us toe line 22. So I think that's where our problem it's at least starting there. So why don't I comment out that line of code, prevent the problem from happening, and then what I'll do is I'll think Well, if the problem is, they stopped. Show delete selected. We've gotta know more about this. What is this? Online 22. Well, I'm gonna put a do a consul dirt here, and we can inspect this just to sort of figure out. Is this really what we think it ISS And remember, when we see the keyword this we think context, so is the context. What we think it is online. 22. So save that and let's go back and refresh the page and then click the select button. And I see something here in the console, etc. But not select. So this looks to me like a dom element. I mean, I see properties like child knows and Children and class list and, um, this style property. So this is a domino him. In fact, it's the element that was just clicked. So that means that I'm thinking online 22 that this the context is this app object. And I could just call this stunt shoulder lead selected. But it turns out that this online 22 actually resolves to the button that was just clicked . This button right here and that makes perfect sense because this is the click event handler , and the click event handler is executed in the context of the moment that was clicked. So it turns out that this is not what we assumed it was. The context is different than we thought it was. We found that out by doing council dirt, so we need to fix that. So let's take a look at troubleshooting example. Number four. First, let's run it and see how it works. So if you go down the troubleshooting example, Number four run that code and we click select. And in each case, when we click the select button, the select button disappears. De select shows and the element it the selected classes toggles. Everything works as we expected. Let's figure out why. Well, what happened on my number? On in troubleshooting? Example Fours Online 22. Instead of saying this thought show delete selected, we said APP should not show delete selected. And the reason that works is because APP is a global variable on because of lexical. Scoping this function is callback function has access to the variables defined outside of it. It can see outside of itself. So we just reference app instead of this and we say app that show delete selected and it works fine. Now, part of the way that we fix this is if you remember an example. Number three. We just passed a reference toe app that salespeople it aerator to each iteration of salespeople ally. But here example in before one of the things we also did is that we pass a callback function here and then we execute at that Salespeople iterated. And that's also a way that we help solve the problem. Because now app that salespeople it aerator is not being executed in the context of the button is just being executed. So and what kind of sounds odd? I don't want to get too deep into that. But the point I'm making here is that we change the context in which app that salespeople, it aerator is being executed. And we also just simply reference the app global variable appear Teoh solve our problem. Now if you look example into five, there's another way we could do it which is? We set a reference to this by creating a variable called me and down here in line 21 we referenced me. So what happens is once again we changed the context on which the app that salespeople it aerators being executed now is being executed in the context of app. So that means up here we have reference to the app um variable, but we can reference it by this, for example, of I were to to a council Durst statement appear on this line on line 17. We can see what this is on each execution of dysfunction. So I'm gonna go to troubleshooting example. Number five. Execute that and I get 10 objects of my console and each object is identical. It's the app object. It's gotta show delete selected method and the salespeople iterated method. They're the same object every time. And the reason we see that is because when we execute their time, every time his function gets executed, this online 17 resolves to app. And that's good. We like that because then we can set a reference to this which is me create variable. And this function can see outside of itself because of lexical scoping. So we can say me that showed delete selected. Now this is a little hacky. And if you have discovered ECC rescript 2015 you may know by now that fat arrow functions essentially sought help solve this problem. Um, so that's definitely topic for a whole nother class. We can get into fire of functions. But for now, the point I'm trying to make is that we want toe in trouble shooting our problems. Way wanted. First determine is if it's a scope problem or a context problem. And then once we know the answer to that question, we can kind of drill down and use different techniques to solve the problem. But knowing what kind of problem it is really makes a big difference in terms of figuring out how are you going to go about finding out where the problem started and how to resolve it?
32. Class Project: before we go, I'd like to take a moment to talk about our class project. This class project comes in two parts. Part one is to build out the Acme Travel sales team dynamically, and Part two is to re factor the example. Web page code. Let's talk about Part one. First, building out the act. We travel sales team dynamically. So right now the example webpage you've seen for the last hour or so is has HTML for the Travel Acme Travel Sales team that HTML is hard coded theatrical index dot html File has always market that you see on the left side, and that markup is rendered in the U I when the page loads. I'm not too thrilled about that approach because if we wanted to make some changes, it would involve digging into the HTML. And I think that's kind of messy for a job script application. I'd like to, you know, kind of control everything with Java script. So what I'm looking for you to do is chop out this approach and convert the acne travel sales team information to Jason Data and then run that Jason Data through some JavaScript code and your JavaScript could would then populate and on order list and then render that a non ordered list in the Web page. That may seem like a bit of a challenge, but I think we've spent a lot of time discussing the difference between scope in context and JavaScript, and you can leverage that knowledge to accomplish this task. I think you've got the tools that you need to get it done. Part two of our class project involves re factoring the example Web page code. What I mean specifically is I'm looking for you to eliminate repetitive code, remove hard coded values in the Java script and then trimmed down bloated functions. So if we jump into some code, I can show you exactly what I'm getting at here with both parts of the class project, Take a look at the file index that age team. Now, at the very bottom of that file, you'll see a reference to app dot Js. Let's look in Js slash ap dot Js So in jazz app dot Js This is the code that we haven't discussed this code in this class, but it's the code that runs behind the scenes that just kind of builds out this application . It mainly provides thes features. It allows you to load the coating, run the code, examples it directly from the page. That's mostly it. Um, but what I do is I run at that start in an app that start I call apt upload examples. Jason. So apt. Upload examples. Jason, I make an Ajax call to this file. So let's copy this and look at the file. And if I just chop out the rest and go here, you can see that this is the actual Jason I get. So this Jason represents what you see in the dom here. All of these examples is thes list itis let this one ordered a list of example. Code links are generated dynamically on the fly. And I'm using ah, Js examples dot Jason. So this code you see right here is exactly what you see here. Okay, So what happens is I, um I load that Jason. And then when that succeeds, this method is called, and I iterated the examples of examples in the Jason and for each example, I build out a list I am, and I can can prove this by maybe just depending a string here where I say example dot name . And if we refresh the page, you'll notice that I get the word holo after every every item here. So, um, the point here is that I'm just This is just showing you that this is is where that list of example links gets created. And as I create each each list item I appended to you l dot example Sophie, we inspect the page, You'll see there's an UN ordered a list with the class examples. This is ul dot examples here, so I'm building it here. So your project, your first project, would be to do the exact same thing with the list of salespeople. So this markup, right? Uh, here in the page, all these thes sales people that you see that's actually hard coded in the HTML. If you look back at index, that HTML, this is your list of salespeople starts right here online. 29. So sales person zero says person warnings and so forth. But these are the salespeople. Here's a one particular sales person, Bobby Carney. And if I look at the first person, it's Bobby Carney. So your project would be to take this market, which is really, um, it's messy, right? Because if I want to change the way these list items are constructed, I have to change each one of these list times in the markup. So hard coded markup isn't really good in these kind of situations. It's better. It's usually better to do it dynamically, so you have more control. So see if you can figure out a way to take the exact same approach. Take these list items, the data and these list items First, put it into Jason. Do you want to convert this information right here for each sales person? You want to convert that information to Jason That's formatted in a way similar to this. And then you want to call that chase and just like we do here and when you call that Jason with Ajax, then you want to build out the allies for each sales person, and you want to shove it in the page so you'll first start by taking this one. Ordered a list and you'll empty it out. Who like this. If I save this now, reload the page. We get no sales people so it's chopped out the lips. So you want to chop out that list and you want to take this in order to list this mark up and you want to convert that to Jason and then you want to pull it into the page, constructed dynamically doing that. It shouldn't be too difficult, but it will require you to leverage the understanding off scope and context that you've gained in this class to build out the jobs group that dynamically creates that list of sales people in your Examples folder, open up the contact some folder and then select a file method Chaining Now, As I mentioned earlier, this, uh, file contains a re factor version of all of our code we've looked at in this class, and it's a little bit clearer and, in my opinion, easier to ah, to read. But I'm using this particular file because it contains the full application code. So if we run this file in this example in the page method training, it allows us to do everything. We can select a sales person and de select a sales person, select multiple salespeople, weaken, delete each sales person individually, or we can select multiple salespeople and delete the ones that are selected. And as we delete salespeople, the total count of the sales team decreases. And at any given time we can reload the page. So but there's two things in this code that I think could really use of improving. First of all, there's a lot of hard coated strings. For example, we we have sales person ally and total sales people container. I mean, these are just strings. And if I I want to change this reference if I want to change the I. D salespeople, well, how many times is that appear in my code? It appears five times in my code. So if I were toe come up here and the dumb and maybe in our markup, we changed, you know, sales people to team Well, then I have to find out how many times in my code sales, the sales people occurs and I've got to change each one of them to team, and that's that's really tedious. And we don't want to do that. I wish we could just do something like this. Just change it here and boom. It changes every place else or everyone who references that element. Just this gets this eso we don't we want We don't wanna have these hard coded string values here. We want to find a better way to do that. And the second thing is that we've also got some repeated code when it comes to, um, we've got functions that a really big that have repeated code such as bind user items, event handlers. Well, that goes from line 74 Tow line, one twenties. That's almost 50 lines of code for one function, which is kind of a lot. And a lot of it is that we're seeing autumn, the item that find something on click item that find something else on click and item that find something else on click. So I'm thinking that each one of these could be broken out into a sub function se, and then this one could be broken out into a sub function, and then this one could be broken out into a sub function. And in each case, all those functions definitely need arguments. So you're going to have to, ah, figure out a way to pass each function, the arguments that it needs to do what it's got to do. But this is so much easier to read. I mean, this bind user items, event handlers Method now has 14 lines of code as opposed to 50. It's a big difference is it's also easier to read. And if we decided that we wanted to change the way the code is composed, we could just do that. But it's just so much easier to look at and to manage. So the two things you want to do in your second project is to remove all of the hard coded string liberals throughout our code. You can set them to be variables or properties of an object that's completely up to you. There's more than one way to go about it, and we were looking for is how you decide that you want toe re factor the code to get rid of all these hard coded string liberals. And the second thing is, is that we want to re factor any large functions such as this one, so that the code inside of is broken up into smaller functions. But you're definitely going to have to leverage your new understanding your new deep understanding of the difference between scope in context in order to provide these functions the arguments they need to do the work that you're asking them to dio Good luck with the class project. I'm really looking forward to seeing what you come up with. If you have any questions at all or you feel like you're getting stuck somewhere, please be sure to get in touch. And I will follow up with you and do anything I can do to help you out.
33. Thank You!: thank you for enrolling in this class where we learned about the difference with teams, scope and context in JavaScript. I hope this was helpful to you. Join me at blogger dot kevin Chisholm dot com, where you will find tons of articles and editorials about many different Web developer topic. Thank you again from rolling, and I will see you next time we owe.