This course has been updated! We now recommend you take the JavaScript: From First Steps to Professional course.

Check out a free preview of the full JavaScript: From Fundamentals to Functional JS, v2 course:
The "Scope Walkthrough, Part 2" Lesson is part of the full, JavaScript: From Fundamentals to Functional JS, v2 course featured in this preview video. Here's what you'd learn in this lesson:

Continuing scope exercises with students, Bianca reviews the questions about scope including local scope's availability outside of a function; when an inner and outer variable have the same name; what happens to scope if a function gets called repeatedly, and more. Bianca takes questions from students.

Get Unlimited Access Now

Transcript from the "Scope Walkthrough, Part 2" Lesson

[00:00:00]
>> So this one says a function's locals scope variables are not available anywhere outside that function regardless of the context it's called in. Tim over here do you wanna start?
>> No, that's boring, yeah, we're declaring first fin, which is a function and not running it immediately.
>> Okay, so we'e defining this function and we have the function body here, we're not running it yet.

[00:00:29] Okay, Dan.
>> We're declaring second.
>> Yeah, we're creating the second function. Skipping over it.
>> We're calling expect. Using as a parameter this function.
>> Yeah.
>> And we don't know that it's necessarily going to be executed.
>> Yeah, but I'll tell you that, yes, it is actually gonna be executed.

[00:00:58] But it doesn't, there's nothing here telling us for sure that it's being executed. But I'll let you know that inside that expect function, it will execute this function. So, Jimmy, so this function is being called what happens next?
>> I don't know all that where the to throw brings it to.

[00:01:27]
>> While we're still actually running this function, so we call this function. But when we call a function, we first need to enter into the body of the function and execute what's inside.
>> Okay, so then it's calling the second function or second Fn within there.
>> Yeah, so it's gonna call that function and then Josh.

[00:01:47]
>> Goes back up to the second function declaration and executes the code, which will deal with the problem.
>> And then ultimately what happens? So, we're executing this, so what happens?
>> That then fall for the throw error?
>> Yeah, so this is probably our error because local the first function is, excuse me, [COUGH] is in a different scope.

[00:02:23] So we don't have access to localToFirst function. So we're trying to assign something that doesn't exist. It's gonna throw an error. So that's where this to.throw comes from, okay? Any questions for that one, okay? Aisha, do you wanna do the next expect?
>> Functions defined and declared the first function.

[00:02:54]
>> So we define this function expect somewhere in the internals is gonna call it. And then Cameron, what happens once it's called?
>> It calls first function.
>> It's gonna call the first function and Eddie, what happens next?
>> So inside the first function up on line 64 for localToFirst function is set to the string first.

[00:03:28]
>> Yep, okay, Chris, what happens next?
>> And then it calls the second function again.
>> Yeah, and then Abdi, what happens next?
>> Run second function and assigns The localToFirst string to be first assigns that to actual.
>> Well, This is in a different scope, though, than this one still.

[00:04:03] So as you would read it, it first looks. Is this variable in this scope? No it's not. As you would read it, not necessarily how it's executed. You look then to the parents scope, which is not this one. This one is not in the same scope. You can even see when you collapse them there, there are siblings.

[00:04:27] So it will look out into this scope here, And then it will look out into this one. And nowhere have we defined the localToFirst function, that makes sense?
>> So the hierarchies are sort of defined statically.
>> Yeah.
>> All right.
>> Yeah, it's called lexical scope. If you want the Wikipedia word for it, but it's as you would read it, to like where it's visually on the page.

[00:05:03] Yeah, okay, so we don't have access to this. It's gonna throw an error
>> And then expect it's called with actual equal to null.
>> Awesome, so actual is null again, because before each it we are resetting our null or actual value to null. Great. Next one, it's a little bit longer.

[00:05:40]
>> Can I ask you about the last one too?
>> Yeah.
>> Is it by any chance a matter of order? Like if second fun was declared for the first time, would you be call it there?
>> If we, for example, put this function above.
>> Just above it, it's.

[00:06:00]
>> No, it still wouldn't work cuz it's about the block that it's in,
>> I guess I'm confused because when I write a big page code or something, and I'll have other functions on that same level that I call side there and I'm missing why they're outside of scope in that case.

[00:06:26] I think you said it pretty, pretty clearly there and it's just not clicking.
>> Yeah, so when you put a variable inside of a function, it's local to that function. And when you do a look up, for example, this is a creation, right? We're declaring this, and this is a lookup, right?

[00:06:43] We're looking at the value of that function. It's first gonna check in its own block. Okay, and we haven't declared anything here. We haven't assigned anything. So it's not there and then it's gonna look up. Okay, and so up is in this function and when I say up, I don't mean like up the lines, but up the scope tree to up into the next parent function.

[00:07:12]
>> Sure, so if I can, like if we're at this step here, when we're calling it from the perspective of the first one, right? Okay, I want to assign this variable, okay? I did that, now I'm calling a second function. What is second function? I don't have that.

[00:07:30] Let me go up a level, but then why doesn't it see, the function, right there var second fun.
>> It does see this?
>> Does.
>> Yes.
>> Yeah, because second font is being declared a parent scope.
>> Wait, yeah, why would it throw an error because you're actually looking for the variable name and not the function?

[00:07:55]
>> So localToFirst function is the thing that's throwing the error This one.
>> Wait.
>> Well, actually, this one, sorry, that was thrown in there. Because it's first looking in here for something called localToFirst function and it's not there.
>> Okay.
>> Then it looks here, and it's not there.

[00:08:23]
>> Okay,
>> And then it let's keep going up until it says, well, it's not it's not there.
>> Okay, so I think, the reason that the second test there that we were looking at fails, is because it calls first function which goes into second function. And then second function still does not have access to localToFirst function, okay.

[00:08:39]
>> But I see what you mean about the order. And I think that's something important to point out is the order. Because it seems like, this wouldn't have access because this is underneath, right? That's what your assumption was, something to do with that?
>> Yeah, there are so new situations that comes in.

[00:08:54]
>> Yeah, and so, that's an another part of sculpt that comes into play which is, when things are defined in the order in which things are defined. So, because first function isn't run until down here, we actually have executed all of this, right? We declared all of this, right?

[00:09:20] You remember that? And then we called first function when we go up here. So, the second function has already been defined. Yeah, that's why that works.
>> Thank you.
>> Yeah, no, that's a good question. Awesome. Okay, so the next one is, if an inner and outer variable share the same name, and that name is referenced in the inner scope.

[00:09:47] The inner scope variable masks the variable from the outer scope with the same name. This renders the outer scope variables inaccessible from anywhere within the inner function block [LAUGH]. Where did we leave off actually? Okay, Michael.
>> We're making anonymous function.
>> Well, actually we start here.
>> Okay, cool.

[00:10:17] We are defining a variable same name, setting it to outer.
>> Yep, so we're defining the variable same name, setting it to outer. What's the next thing that happens? Who's next? Did you just go?
>> Yeah, I did, but I can go again.
>> No it's okay. So, it's either Vin or Aisha.

[00:10:41]
>> I'll go, a functions to find.
>> You define a function, okay, ultimately.
>> I was just reading the description trying to understand.
>> Yeah.
>> Okay, so we defined a function, then we called it.
>> Yep. And then we call the function, Josh.
>> Evaluate the function body.

[00:11:08] So, setting it to enter places, same names are used.
>> Yeah. So, we declare a variable with the exact name as this variable same name. We reassign the value here. And then, Jimmy.
>> Is it a matter that you're redeclaring it?
>> Not really.
>> And it's gonna jump down to 91.

[00:11:36]
>> Well, we have this one here first. What setting actual, it's the same name.
>> And what is same name?
>> Inner.
>> Okay, and then, Ryan.
>> Expect, is called
>> Okay, so we exit this function and go to expect. You wanna take a stab?
>> Sure, actual at this point is still inner.

[00:12:07]
>> So, actual is enter You have a question about that?
>> So, would that be a case where if you don't want that behavior we'd use let to create a block scope?
>> This is similar to the example with let. So, instead of creating the block scope we're creating a function scope, and we're doing what's called masking.

[00:12:35] So, we're masking the value, because remember you first look at your most local scope to get the value, if you don't have it then you go up. But if you have it, and you also have on your parents scope, you only find the one on your scope because you don't look up if you find a value.

[00:12:52] Does that make sense? So it's like, what is this? Head, shoulders, knees and toes, just like that, okay, That makes sense to everyone? What if we did this? Wait.
>> You copied the next example.
>> Yeah, [LAUGH]. Oops, maybe I've done this too many times. Okay, or you have a question?

[00:13:28]
>> Yeah. Sean's saying, he's just checking his understanding if line 87 was declared with a let. Would we still get the same result because it's scoped to the block?
>> Yeah, it would still be the same. Let in this case, doesn't matter. Let in this case doesn't change anything, because we have a function scope.

[00:13:53] And the let keyword only creates what's called block scope, which is something that we didn't have before. So, for if else statements we could have a scope for that, now with let. Before that, if else statements, if you declared a variable in a loop, or in brackets, or in a switch statement, or anything like that, it wasn't local to that block.

[00:14:23] And so that would cause kind of some weird behavior especially if you had like a lot of FL statements, and reassigning variables and stuff like that. And there's also hoisting that happens, which we'll talk about. And so it can be misleading. And so we introduce let by we, not me at all, I was not involved in that.

[00:14:43] Let was introduced into the language which creates block scope, which enables us to have variables that are private to something other than a function. Before that, all we had was private function scope. Any more questions about this one?
>> I'm still not quite getting it. Because it's looking at actual array.

[00:15:03] And actual was defined as no before this test. Is that function returning actual to the outer scope?
>> So, this variable lives in the variable
>> Because it's a global variable in this kind of context.
>> Yeah.
>> What we change it inside, it's changed outside. Okay, no matter

[00:15:27]
>> Exactly. So, it's reaching up, changing it up there so it will be except, access to anywhere else it would be the same value. Yeah, cool. So, line 94, if an inner and in array variable share the same name and the name is referenced in the outer scope.

[00:15:50] The outer value binding will be used. So, this is kind of the opposite of what we just did.
>> And where we leave on? What are we trying to move? 95.
>> 95.
>> That's something we just did.
>> Looks very similar, doesn't it?
>> So declaring a variable, same name?

[00:16:13]
>> Yep, so we declare the variable, same name, we assign it to outer. I'll skip ahead, we are defining a function and then we call the function, and then what happens?
>> Thanks for giving me fun stuff. So inside the function body, we declare the same name variable and we give it the value inner?

[00:16:34]
>> Yep, so same name, we assign it to inner and then it exits. Let's see, what happens next? So we were just here, we just run this.
>> Line 100, set actual equal to the value sameName which is. Outer.
>> Yep, which is outer. And then we should expect actual to equal?

[00:17:08]
>> Outer.
>> Outer. Cool. All right. So this one a new variable scope is created for every call to a function as exemplified with a counter. So let's check this out. Christina you wanna start?
>> Sure, there's a variable created fn which is a function.
>> We create this function save it in a variable, and then what happens?

[00:17:52]
>> Then we run that function?
>> We ran the function, so we jump into that function body. And Jamie
>> And then we're setting inner counter to. 10, basically.
>> Yeah, so we're setting inner counter to 10 because at this point inner counter is undefined. And then Michael, what happens next?

[00:18:16]
>> We are taking inner counter, send it to an account of plus one.
>> To inner counter.
>> Yeah I can read it by itself in the same line, right? So that would make it 11.
>> Yep.
>> Actual to be set to 11.
>> Yap. And then so we exit the body of this function, we find ourselves on line 113

[00:18:38]
>> So we expect that to be 11.
>> Yeah, we'll expect that to be 11. Okay, this is gonna seem repetitive but it's actually very important. I should keep going. I'm like, do you want to but really what I'm saying is, you have to, all right, you don't have to, strongly encouraged [LAUGH].

[00:19:03]
>> The function is declared again.
>> [CROSSTALK]
>> It's being invoked, yes. So we call the function and then we hop back into the function body, what happens next?
>> So now we are dealing with inner counters 11.
>> So, what is this line doing?
>> So we say the inner counter is actually inner counter or 10.

[00:19:37]
>> So what is inner counter?
>> 11.
>> Where does it say that we're defining 11?
>> When we define on line 113.
>> Yeah, so that's a common misconception. But what happens is whenever you call a function you create a brand new function scope every time.
>> So then it's ten?

[00:20:05]
>> It's ten.
>> So then we say inner counter to b itself plus one, so that's 211 again.
>> It'd be 11, actual visa to 11. And we expect actual to equal 11, awesome. Any questions about that? So this is another like kind of gotcha, but very important.

[00:20:32] Every time we call a function and when we get to closures, this is gonna be really drilled into your head. Every time we call a function with the parentheses, invocation operator, a brand new scope is created. Some people call an execution context, and so you can think all the variables in that scope.

[00:20:57] When the function is called, it's gonna be initialized as whatever they are, in this case 10. And then you do it again, it'll be initialized again. So they're separate, they don't talk to each other. Do just two different worlds of scope. So next one is a new variable scope is created for each call to a function as exemplified with uninitialized string variables, okay?

[00:21:27] So I think we left off with you Ryan
>> Function is named and declared.
>> Yeah, function is named and declared and then it's called, we execute the function body, then what happens next?
>> We're executing function body, sorry.
>> Yeah, we're executing the function body.
>> Declaring local variable not giving it ability.

[00:21:56]
>> Yep, we're declaring this variable, when it's not declared it holds the value undefined. And then we check if it's undefined.
>> Since it is undefined, that'll return true and we'll execute that statements and so we'll set actual to this text the string alpha.
>> Exactly. And then since we entered into this if block we will not enter into this else if so this gets skipped and we go down to the next line what happens here Cameron?

[00:22:31]
>> Variable is set to initialized.
>> Yep. And then Eddie what happens?
>> Then we're going into the expect and actual will equal. Alpha.
>> Yep. Then we're gonna call the function one more time, we're gonna enter into the function body, we're going to initialize this local variable, what happens next Chris?

[00:23:08]
>> The local variable is initialized so it will call the else statement actual equals omega.
>> So, we actually read.
>> So when we call the new function, it's gonna create a brand new scope.
>> So it will be undefined again?
>> Yeah, it's okay. So then what will happen, Audy?

[00:23:37]
>> Once it's undefined, we'll set actual to equal alpha. [INAUDIBLE]
>> And then we go down here, we set localVariable to initialized, but this is still alpha.