Check out a free preview of the full JavaScript: The Hard Parts course:
The "Q&A: Lexical Scope" Lesson is part of the full, JavaScript: The Hard Parts course featured in this preview video. Here's what you'd learn in this lesson:

Will takes questions from students about closure including defining lexical scope, which is the available data when the function was defined.

Get Unlimited Access Now

Transcript from the "Q&A: Lexical Scope" Lesson

[00:00:00]
>> So we're gonna do thumbs in a second and really hold yourself accountable. There's [INAUDIBLE] fantastic clarifications to be asked about hold on how is this even, working what's going on here.Griffin will you kick us off with your clarification.
>> Does this stay via like through page reloads.

[00:00:19] Through page reloads. If you are totally refreshing your page, I mean, you will restart your JavaScript loading from scratch. Now, if you are, you know, typically doing that a lot of the time nowadays, if you are doing what you more typically doing, which is like, You know, collecting more tweets.

[00:00:40]
>> Changing the state of [CROSSTALK]
>> The state of the page, absolutely. But if you're refreshing your JavaScript file is reloading from scratch. You're starting at the top all over again. Good question, I've never had that question before, it's nice.
>> Is there a way to, how can I locate that data if I wanted to save it for a page reload that I could load back in?

[00:00:59]
>> Yeah. Where is this data? Can I just do myFunction.counter do we think? Uh-uh, this is not sitting as a property or minute function. This is no. Actually, let's now add where this data is stored. I don't know where it's stored, but how the bond gets made. I said that when increment counter is to find inside of the outer Execution context.

[00:01:23] When we're running outer, when we run outer we create a counter zero. Increment count as a function and then we return this increment count function out to my new function. And we call my new function and so on. When we define increment count, we just said we make a bond between the increment counter function.

[00:01:41] Make a bond between it And it's surrounding life data. Where is that bond? What is that bond? Or if you look in the JavaScript specs it's defined we don't get to see it. We can not do that increment counter.backpack or whatever it is not in that book. It makes the bond using this special property called, does anyone know?

[00:02:09]
>> It's not that, it's this guy here, square bracket, square bracket, scope, square bracket, square bracket. The function gets a hidden property Behind the scenes of it. So if I were to console log incrementCounter, this is a function definition. There's no dot, square bracket, square bracket, scope, square bracket, square bracket.

[00:02:32] It's just a definition. Behind the scenes it has a special bond. Square bracket, square bracket, square bracket, square bracket, square bracket. Yeah, that thing I just said. Square bracket, square bracket. So, scope-square bracket-square bracket is a hidden bond of the back of the function definition where we make a bond to the surrounding store of live data.

[00:02:54] Now, that is only accessible. How can I access that live store of data? By call answers it by doing my new function .scope.counter Is not available there. It's only available from where, Aman? Where is it available from?
>> That was gonna be my question.
>> It's only available from the call to this function.

[00:03:16] I want to access this data, I've got to call my new function inside of which, if I make reference to something that's not available in local, I get access To the back pack, to the square bracket, square bracket, square bracket, square bracket, JavaScript has something, what we’ll see in a second, but for now, this pond her is made behind the scenes, the state to it is only accessible when I call the function, I have to write my function In this case we've got a increment counter in a really smart way such that it can be, has all the functionality that I ever want to interact with the backpack.

[00:03:56] So I might write for example increment counter takes in a parameter which when I call it. Refers to something that is not in local but refers to the backpack value of counter and updates the backpack value of counter. If I wanna get my backpack data out, I'm gonna make sure that I return counter.

[00:04:14] Well counter isn't in local, it's out here, so I'm gonna get that backpack value out the bottom of the function. That's how I get access to it. But this bundled up data here is protected. I can only get access to it from inside my function call when I call the function that has The backpack bond to it.

[00:04:34] All right, so that's one. Still there's more clarifications which can draw out more of the subtleties of this. Katie?
>> That was part of my clarification. I was trying to understand if when you call, my new function If it's really just referencing that?
>> When we return out the icnrement counter funtion with it's little backpack of data.

[00:05:04] That backpack is defintely not a copy. It's the original data that was created in here. But instead of normally when we finish running what happens to all this data? Somebody said it. Andrea, when we finish running what happens with all this all data?
>> It's garbage.
>> Garbage.

[00:05:20] JavaScript goes, hold on. Hold on. The function that got returned out. If it gets called, shit, it's gonna make reference to something that was still defined in here. I better not let garbage collect that. I better leave that in the back half. And that brings me to a real subtlety, JavaScript's engines try and optimize this.

[00:05:39] Suppose we defined 100 different variables inside of here, each with different numbers or whatever. I mean only ever refer to counter, do we want all that data kept around in a backpack? No, so JavaScript will actually, the bond is when the function's defined is made to the entire surrounding variable environment.

[00:05:58] It's surrounding live data. But when that function gets passed out, JavaScript does it's usual garbage collection like hold on everything, we've got some references to data. If I run my new function, if I run this. Increment counter function under it's new label myNewFunction. Inside of it, it references counter, ah-ah, we better make sure we hold on to the data in the backpack that could be referenced.

[00:06:24] But there's 99 variables here like, I don't know, counter 1, counter 2, counter 3 that are never used. Remove those from memory. You don't need those. So Java is actually only going to hold to the increment counter function here. That ain't used inside my new function. So increment counter will not be stored in the backpack.

[00:06:45] It takes only the data, takes the whole backpack, the whole surrounding variable enviroment but only persists Only holds onto the stuff that could ever be referred from inside the returned out function, cuz we can only access its backpack data from where?
>> From the function itself.
>> From the calls of the function.

[00:07:04] So if we didn't write this function, we defined this function inside of here. So we didn't write it to refer to anything else, no one's gonna access that live data But look at this. Our function that got returned out, my new function that's called increment counter inside. We returned it out.

[00:07:22] We did not just get a function out. Now do we see why it's so powerful to design a function inside another function. We didn't just get a function out. We got a function plus a backpack of live data. And now I think it's time to reveal what people actually call the backpack, because obviously you can't say that forever.

[00:07:40] People actually call it, colloquially, I hate the colloquial term for it. People call it, they say, this is the closure, or this is a closure. I hate that, some people call the whole concept closure and they're not sure, they don't mean the backpacks. But people would typically colloquially say my new functions closure.

[00:07:58] This is the closure. I love this term. I think it's super precise. I like to call it the closed over variable environment. The closed over variable environment. C-O-V-E. The cove, I'm going to make that one big as well. The COVE. This guy here is the code. You can also call it this.

[00:08:18] You can also call it this. When a function is defined, increment counter is defined inside of the called outer. It gets a square bracket, square bracket, scope, square bracket, square bracket, hidden property The reference is its local memory or variable environment, the same thing, where it has been defined.

[00:08:40] So when I then return out that function, as we do when we call we return our incrementCounter and store it where? Lindsay, when I call it when I run and create incrementCounter inside of it, where do I then store the incrementCounter function? In my new function.
>> Excellent, my new function.

[00:09:00] Wherever I call that functionality, wherever I run invoke execute that functionality, increment counter function, it will always look first in its immediate local memory. Fine, we know that. But then, before it looks in the next execution context out It will look in its scope, its square bracket, square bracket scope, square bracket, square bracket property, in its backpack.

[00:09:29] Or we could [SOUND] call it, in its lexical scope. Because this bond here, to the surrounding live data, is known as Lexical scope. It's the I am determined, my functionality when it gets calls, values that are available, variables that are available to it are determined from where I was defined, not from where I was called.

[00:09:51] I'm being called in global, but that's not telling me what data's gonna be available to me. What's telling me what data's gonna be available to me is where I was defined And there, JavaScript static or lexical scoping. This is what it means when we say JavaScript is lexically or statically scoped.

[00:10:11] That means, lexical means the position of my function definition, not where it gets invoked, is ultimately what determines what data I will have available to me when my function does get invoked. So we might think where I run the functionality, it was born in here, out here, and it references counter.

[00:10:31] If I'm local, my next function's being run in global, we're in global. But we don't look at global first because our lexical scope, the available live data when our function was defined, the available live data around me is what determines our available variable Variables and the prioritization at function execution.

[00:10:51] Not where our function was called. My new function was called here, but because it was defined long ago inside the called author, it never lost its lexical scope reference. So that when I call the function, I always go look in the local first recalls. But I always go look in my let's go scope reference, my let's go scope reference.

[00:11:12] Backpack before I ever look another layer out. I always look in my backpack first, my lexical scope reference first, or I call my new function with my [INAUDIBLE] first. My close over variable environment got closed over and pulled out of the variable environment. Or the colloquial term that I don't love, my closure.

[00:11:39] And the colloquial term that I do love, my backpack. There's a lot of terms for it but I guess the most precise is my lexical scope reference. That's the guy that refers to The little bond that refers to the surrounding data. Closed over, variable environment, closure, the function comes out.

[00:12:04] And it's still got it's back pack on until yeah, it's there. It's attached to the function. All right.