The 10 Days of JavaScript: Day 8 (Variable Scope & Context / this keyword)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] hello everyone and welcome back to the ten days of JavaScript here we are in day number eight and in this lesson we are going to talk about scope and context so what is scope and what is context well here are my own sarcastic definitions so I would say that scope is the biggest source of confusion regarding variables and my definition for context would be the biggest source of confusion regarding objects now these tongue-in-cheek definitions are not actually helpful but right away they do let us know that scope has to do with variables and context has to do with objects but beyond that let's dive deeper so let's start with scope and then in the second half of this lesson we can cover context now instead of trying to explain scope with only words let's work through a few examples together where we can see scope in action so imagine we have a variable I'm going to say let my name equal a string of text and now let's try to access this variable from within a function so maybe down here let's create a brand new function you can name it whatever you want I'm going to name it maybe amazing function parentheses curly brackets and just as an example let's try to log out to the console the my name variable just to see if we have access to it so console dot log my name okay and then let's actually call or execute this function to test it out so on a new line we can just call that function amazing function okay now if we check the console awesome now this is just review we've already done this before so the question is why am i showing this to you well it's because the topic of scope has to do with where we can access a variable from let me show you what I mean so this code is working perfectly but what if we move this first line of code here what if we cut and paste it to live within the function let's try that out let's cut this first line into our clipboard and then inside the body of our function maybe right above the console line paste in your clipboard okay and then let's cut and paste this console dot log line let's cut that into our clipboard and let's move it down below this function call now at first glance as a beginning programmer we would think that this would work right we've got this function that's going to create a variable named my name then we are calling the function so we know that that code is going to get executed so we would think that we would be able to log out to the console my name but if I check the console we just see a big error message that says my name is not defined so we just smashed our head up against a brick wall and this is our first example of running in to an issue with scope now before we worry about what the word scope means in this sense let's first answer the question as to why this code is not working why are we receiving that error message in the console well it's because within the body of this function or I should say within this block of code within these curly brackets as far as variables are concerned we are in our own little new world that is separate or private from the outside world so we would say that this variable is scoped to this block these curly brackets meaning it cannot be accessed from outside the block so down here when we try to access that variable as far as this line of code is concerned this variable doesn't even exist now let me put things back to the way they were at the beginning of the lesson and explain why that was working so let me cut the variable line back up out of the function up at the very top here and let me cut and paste the console dot log line back into the function now this code will work just fine it works because up on this line when we are creating the variable we are not inside a block or any curly brackets right we are just out in the open in what we would call the global scope this works because scope is like a one-way street the traffic only flows in one direction code can reach outwards to access a variable but it cannot reach inwards now don't worry I don't expect you to understand what I just said that's why we're going to work through a new example right now to understand what I mean by inwards and outwards so right now make sure your code looks like mine if you need to pause the video for a second to catch up that's okay inside our function I want you to cut the console dot log line so just cut it into your clipboard and in its place let's write an if statement so let's say if parentheses for the condition why don't we say if 2 + 2 double equal sign for right because we know that will always be true right after these parentheses let's include curly brackets and drop down and now inside the if statement let's just paste back in the console dot log line okay now if I check the console we see that things are working just like before the if statement so you might be wondering why I even added this if statement at all well it's because it's a great example to explain what I mean when I say that scope begins in words and moves outwards right that analogy when I said that scope is a one-way street so when this line of code runs Java scripts first instinct is to see if there is a my name variable as close to home as possible meaning within this scope within this block within the curly brackets for the if statement so just as a quick test within the if statement right of the console dot log line if I say let my name equal Brad the third and then check the console we see Brad the third however if we either delete this line or just put two forward slashes to comment it out and pretend that it's deleted if JavaScript sees that there is no my name variable within the current local scope well it's then going to look up the scope chain or look one level outside of itself so outside of this scope the next closest scope is within the body of our function so just as a test if we said let my name equal Brad jr. and check the console we see Brad jr. okay and then finally if we either deleted this line or just got rid of it with two forward slashes JavaScript would say okay there's no my name inside the local block there's no my name in the block that's one level up why don't we check another level up from that and that would finally land us in the global scope and it would see that AHA that variable exists if we check the console it's back to just Brad so the idea is that when a line of code runs and you're looking for a variable javascript is first going to look for that variable as close to home as possible within the current scope if it's not there it's just going to keep moving up the scope chain one level at a time until it finds what it's looking for now it's important that we really understand what's going on here so really quick this is not a case of these lines overriding or updating this original variable that is not what's happening even though these three variables of my name all have the same identifier or label name they are three completely independent and separate variables let me show you not only how we can prove that but also what I mean because I remember when I first learned programming and I saw an example like this I actually misinterpreted it and saw it backwards I saw it as okay we're creating the variable in the global scope and then we are updating the variable in this scope and then we're updating it again in this Co that is not the case these are three completely separate variables and I can prove that to you by removing the slashes to uncomment out these two lines so let's get rid of the slash slash here and then get rid of the slash slash here and now let's do this within our innermost block of code within the if statement inside the console dot log let's begin by saying inside the if statement and then a comma and then output our variable okay now right after the if statement but still within our function so right here let's log out to the console and say in side our function and then comma and then our variable and then finally down at the very bottom on the last line of code after we call the function so we are in the global scope now let's log out to the console and say in the global scope and then comma and then output my name okay now if we check the console we see inside the if statement is one variable with its value inside our function is a different variable with its own value and in the global scope that's another variable with a different value what was the point of this experiment it's to show you that these are three completely separate variables even though they have the same identifier or label it doesn't matter the let statement creates a variable within the current local scope it does not matter if that identifier or label name has been used in outer scope remember that inside a block of code inside these curly brackets it's like our own new private little world as far as variables are concerned meaning it's almost like we get a clean slate we can reuse the same variable names and JavaScript knows that we do not want to affect any of the variables in outerscope we just want to create a brand new separate variable that is scoped to this block now you might be scratching your head right now and wondering well what if we wanted to mutate the global original variable from within our innermost block is there a way we can do that and the answer is yes absolutely just to save confusion why don't we get rid of this let my name equal Brad jr. line and let's also get rid of the two console.log lines within our function okay now within the if statement what if we want it to update or mutate or change the value of the global scoped my name variable well all we would need to do is remove the word let from this line of code the let statement says create a new variable for this local scope but if we get rid of that now we are just trying to work or access the variable and we're setting it to equal something so here's what Java scripts going to do it's gonna see this variable and ask itself does this variable already exist within this current local scope it doesn't so then it's going to look one level up just within the function it's going to see that it doesn't exist there either and then it's going to check one level up and it's going to say okay it does exist in the global scope that must be what you're talking about right here so I'm going to let you update or change that variable this is what I was talking about earlier when I said that scope moves in one direction it's a one-way street inside code can reach outwards for variables but outside code cannot reach inside for variables so long story short we set it to equal broad the third and now down here where we are logging out to the console in the global scope and then our variable if we check the console we see Brad the third awesome now before we switch gears in this lesson and move on to the second half and talk about context instead of scope there's one more scope related thing we need to cover so throughout this course when we've been creating or declaring a variable we've been using the word left however until about three or four years ago there was no let in JavaScript and instead we had to create variables by saying var and then the label or identifier and otherwise the syntax is the same right so if you're looking at older code or if you inherit a project from someone you might see var being used instead of let now there are several subtle differences between var and let but right now I want to show you the one big huge glaring difference between the two the biggest difference between var and let is that let uses block scope whereas var uses function scope so what in the world does that mean let me show you so within our if statement at the beginning of this line of code if we put the word let here we know that that's going to create a variable that is scoped to this block right scoped to the if statements curly brackets so let is going to look for the nearest enclosing block and a block can be several different things right we know that an if statement uses a block these curly brackets we know that a while loop uses the curly brackets in a block clearly the body of a function uses a block okay but the idea here is that let is going to make it so that this variable is only accessible from within the nearest enclosing block so right now we would not be able to access the variable right here outside of the if statement however if we change this to a var instead of a let var uses function scope instead of block scope so var is gonna say you know what I don't care that the if statement has curly brackets and that it's a block since I'm a var I only care about the curly brackets of a function right because var uses function scope instead of block scope this means that this VAR variable is accessible anywhere inside its enclosing function even outside of the if statement so we could access my name right here within the function now again historically that's how we created variables in JavaScript but in the last three or four years javascript finally got access to let and the reason that 99% of developers used the word let instead of var is because almost all other programming languages besides JavaScript use block scope instead of function scope block scope is just what most of us are used to it's a paradigm that we are familiar with and it's a super popular opinion that block scope leads to less confusing code less scope confusion and just less problems overall so long story short that's the difference between let and var but in the current year and looking forward I encourage you to always use the word let and never or I should say basically never use the word var all right and that's scope in a nutshell if you're still a bit confused regarding scope that's okay that's completely normal in fact I have worked with professional mid-level developers who were even sometimes still confused by scope big picture you do not need to be a scope guru at this point I just want the topic to be on your radar it's something you need to be aware of and if your code isn't working you might want to double or triple check your scope and make sure your variables are pointing towards what you think they are pointing towards remember you can always use console.log to check the value okay at this point let's change gears we've talked about scope now let's talk about context so I'm actually going to delete all of the code that we have and start fresh and honestly you might want to pause the video and go take a state-mandated break maybe get a drink water go for a quick walk or if you have the attention span of a champion let's keep going okay so scope is about variables context is about objects so with this in mind let's go ahead and give ourselves an example object to experiment with so I'm going to create a variable and I'll give it a name of John and set it to equal and object curly brackets let's give it a property of first name and set it to equal John and then let's give it another property of last name and given a value of dough okay and then let's also give this object a method named drive car so drive car parentheses curly brackets and let's imagine we want this method to log out to the console a bit of text that says John Doe is driving a car so console dot log only we don't want to necessarily hard code John into the string of text instead it would make more sense to pull in the value of the first name property right because that way if in the future they ever legally changed their name to Jonathan or something different our drive car method would automatically pull in that value so the question is inside of a method like this right inside this function that belongs to the object how can we reference this property well instead of just saying first name we instead want to say this dot first-name now the entire topic of context in JavaScript is centered around the this keyword I will explain how that this keyword works in just a minute but first let's finish out our line of code here so right after our first name let's say plus and then a string of text with a space in it and then let's add on their last name so this dot last name and then let's add on a string of text that says is driving a car okay now really quick let's test out this method and then we can dive into really understanding the this keyword so maybe down here at the very bottom of our code below our object we can say John to work with the object look inside it with a dot and then call that method drive car parentheses to call the method and if we check the console awesome we see John Doe is driving a car again this is nothing new we've done this before the reason I'm showing it to you this time is because this is a chance to dissect the keyword this what in the world does this mean well that's a loaded question even some of the best JavaScript developers in the world if they're being honest at one point in their career they were definitely confused by the this keyword so in our current example the this keyword is pointing towards our John object so if we use our imagination we are basically saying John dot first name John dot last name right we know that to look inside an object you just say dot and then whichever property you're interested in now at this point you might be thinking what's the big deal what's so confusing right this seems really straightforward you might be thinking that within a method the this keyword simply always points towards the enclosing object however that's not the case so in a search for the truth um let me confuse you on purpose just for a minute to show you why the this keyword gives developers so much trouble check this out right above this console dot log line but still within our drive car method let's create a brand new function so function and let's name it I'm a function not a method then parentheses curly brackets this name is just for fun you could choose any function name you want but we are nesting a function inside of this method and check this out inside the body of this function let's log out to the console the this keyword now currently this function would never actually run right this is just a function definition or the recipe for the function so then maybe right below it why don't we try and call that function so I'm a function not a method parenthesis to call it and if I check the console right above our John Doe is driving a car we see this window object let's not get too hung up on what window is for now I can tell you that in the web browser window is the root or global object we could say that it's the top-level object that houses or contains all of the web browsers other objects for now let's just call window the global object now the important concept here is that the this keyword is pointing to two different things at two different times right in this context this line of code that I'm highlighting the this keyword pointed towards our John object but then on this line of code that this keyword is pointing towards the global object so the million dollar question the question that confuses programmers all around the world the question that they're ripping their hair out of their head over is how does Java Script decide what this keyword should be pointing towards well here's the answer the this keyword does not point towards the enclosing object clearly that's not the case if that was the case then this instance of this keyword would be pointing towards John but it's not so the real answer here it is is that the this keyword points towards the object that is executing or calling the current function or in other words instead of focusing on these two lines of code that used the this keyword so this line and this line what we should really be focusing on are the two lines of code where we are calling the functions so this line and this line on this line of code the object that is calling or executing the function is the John object so that's the object that this keyword is going to point towards inside that function now here's where the confusion comes from you might be thinking to yourself well hey this line of code lives inside that drive car function so why on this line of code is the this keyword also not pointing towards John well the answer is because that's not the context in which this function is actually being called or executed the only reason that this function ever actually runs is because we are calling it right here now on this line of code it's painfully obvious which object is calling or executing the drive car function or we should say the drive car method but on this line of code it's not as obvious right it's not like there's an object right in front of it and then a dot so in cases like this when we are calling a regular old function javascript essentially says you know what let's say that it's the global object that is calling or executing this function so that's what the this keyword gets set to when the function runs don't worry I do not expect you to fully grasp this yet my only goal right now is for you to just be aware that that this keyword exists that what it points towards changes depending on the context and that it's a source of confusion for developers of all different skill levels not just beginners in the future when you are creating applications I guarantee that you're going to run into this keyword and I can also guarantee that at some point your code is not going to work the way that you want it to work and there's a good chance that it's because the this keyword is not pointing towards what you think it's pointing towards don't worry this is a concept that we can review and practice again later on in the course not really quick before we bring this lesson to a close I want to answer the question of why why does the this keyword even exist we just spent a lot of energy trying to understand how to use it but what about why we would use it so let's give ourselves a quick goal now right now we just have this one object named John but imagine we had 500 other objects that represented people and cats and dogs and imagine that we wanted to give all of those objects a method named breathe and maybe the breathe method logs out to the console a message that says their name and then it says they just inhaled and exhaled now technically we could just type out a function like we did for drive car and then copy and paste it into all 500 objects but that would be terrible code right that's super repetitive so let me show you what else we can do maybe down here let's create a brand new function it's a function let's call it breathe parentheses curly brackets now if you're more experienced in programming and you're just watching these lessons as a review you might be screaming at the screen right now wondering why I wouldn't just use a prototype or class syntax and inheritance but those are concepts that we have not gotten to yet in this course so bear with me so we've got this new function and imagine inside that we say console dot log and then to save a bit of typing we can literally just copy and paste the code that I'm highlighting right now right so up in the drive car method I'm going to highlight from this until the closing of the quote and then paste that into our brand-new function and then for the ending part of the string let's just change it to say just inhaled and exhaled ok so now we've got this new function named breathe now what if we want to let our John object use the breathe function right so we would expect it to say John Doe just inhaled and exhaled well at first glance this function looks hopeless right because it's a standalone function not a method that belongs to an object meaning how in the world do we expect this to point towards anything meaningful if we tried to call or execute the brief function down here because it's just a regular old function JavaScript is going to consider the global object the object that is calling it meaning that's what the this keyword is going to get set to you the global object and clearly there's no first name and last name properties attached to the global object however check this out here's an example of why it's so amazing to be comfortable with this keyword we can begin with our breathe function and in JavaScript a function is an object just like any other object or entity and functions have access to a method named call so we can include the name of our function and then instead of parentheses right after it to call it directly we can say dot call and the call method is going to call or execute our function but not before first giving us a chance to control the this keyword meaning whatever we place inside these parentheses here call will make the this keyword point towards that so if we want our John object to be able to use the breathe function well this function would make a whole lot of sense if that this keyword was pointing towards John right so down here inside the call parentheses so let's just pass in our John object and now if we check the console awesome John Doe just inhaled and exhaled so maybe now you're starting to see the purpose of the this keyword it allows our code to be flexible if we had another object named Jane or meows a lot or barks a lot we could just as easily include that here and thanks to the this keyword this function is flexible enough that it would still make sense and work perfectly in the future we will learn about other situations where you use the this keyword that are even ten times more useful than this example okay that's going to bring this lesson to a close to be you probably didn't need to know this much about scope and context this early on in your JavaScript career I usually try to err on the side of protecting you from complicated topics early on but really I just feel like scope and context are such a common source of confusion for developers that even if none of this makes sense right now we at least planted these seeds in your mind and maybe a week or two down the road if your code is not working and you're super confused and frustrated maybe a little light bulb will go off in your mind and you'll go aha maybe it's scope that's causing the problem or maybe it's context that's causing the problem and you might even need to come back and re-watch this lesson but big picture I think you're going to be happy that you learned about these topics cool now looking ahead to our next lesson we are going to learn about miscellaneous features of the JavaScript language that are super useful but maybe didn't need an entire video just for themselves so it's gonna be sort of a fun grab bag of useful tips and syntax and tricks it's going to be a much shorter lesson than this one I promise you that so let's keep our momentum rolling and I will see you in the next lesson the ten days of JavaScript is the first chapter from my upcoming premium course full stack JavaScript from scratch I'm making these first 10 or 11 videos freely available on YouTube and so for the next 10 days I'm going to upload one new video each day so stay tuned or if you're watching this in the future all the lessons are up so feel free to binge watch the full premium course is not available just yet but if you subscribe to this channel you'll be notified as soon as it's out or you're watching this video in the future it's already available enjoy you [Music]
Info
Channel: LearnWebCode
Views: 28,741
Rating: 4.9613733 out of 5
Keywords: javascript, this, keyword, scope, context, tutorial, learn, beginner
Id: WPcW83BMT3Y
Channel Id: undefined
Length: 33min 10sec (1990 seconds)
Published: Tue Nov 06 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.