Transcript from the "Scope Review" Lesson
>> Kyle Simpson: So in our discussion of Lexical Scope, we described this process of looking up a variable as kind of metaphorically looking for an office in this office building where you start with the current scope. But you are looking at for an identifier to figure out which bucket or in this case in the metaphor which floor of the building it exists on.
[00:00:20] And say, you start with the current scope, if it's not there, you go to the next outer scope or in this case to the next floor up in the building. You work your way up the building looking for it and if you find it great, kinda first come first serve but if you don't find it, then you reach the top of the building of the global scope and there's no where else to go.
[00:00:40] Now the metaphor describes this as a look up process. And it describes this as something happening at run time. Looking for the marbles, the conversation, the building its all describing it as if it was something that actually has to happen at run time. Technically speaking Lexical Scope does not actually need to resolve it at run time, at least for most of the variables.
[00:01:05] And that's one of the emphasis that we have around Lexical Scope is that it is a compiled time, even that word lex is part of the compiler phase, it should bring to your mind the idea of a compiler type operation. And when the compiler is going through and it finds a variable.
[00:01:24] And it's declared for some scope, it can register with that variable exactly what scope it belongs to. It doesn't need to then go figure out that later. It registers with that variable what scope it belongs to. So in many cases, the lookup process that we described is only metaphorical.
[00:01:41] It doesn't actually need to know that because it already figured out at compile time exactly where that variable was found. And even if it does need to do the lookup, it doesn't need to do the lookup every time. Because once it finds the answer to that question the first time, it's never gonna change.
[00:01:57] Lexical Scope is fixed, it's static. It is a compile time or I like to say, an author time sort of event. When you write code and you put a variable here and then a function inside of it and another scope and you reference that variable. You permanently and eravicably mean that this variable is gonna always reference that particular location that's Lexical Scope, okay?
[00:02:19] And we'll compare that later on in this workshop to the idea of a dynamic scope system which by its virtue of its name would say, it is actually going to dispatch and make decisions at run time. So we'll compare those two but just have it in your heads this idea that Lexical Scope, is this fixed sort of a thing.
[00:02:39] Now I wanted to point out a couple of examples where we wanna make sure that we fully understand scope. Here, you'll notice that I have a variable foo declared in the outer scope there on line one. And that's referencing a function but that's not a function declaration because it shows up in an expression position.
[00:03:00] The word function is not the first thing in the statement. So what happens to that bar identifier. The way we talked about it before earlier in our course. We talked about the idea that when we encounter a function declaration, we would then add that identifier to our enclosing scope.
[00:03:17] But it is not the same for function expressions. Here, that bar identifier will not be added to the enclosing scope which is why down on line 12, we would get a reference there because there is no such bar identifier in the global scope. It does exist, it's just not added to its enclosing scope for function expression their name identifier, the processing are slightly reversed.
[00:03:39] And the name identifier for a name function expression will show up within its own scope. So there is a bar inside of this scope for lines two through eight. That is accessible which is why we can reference it for example on line five. There is bar internal to that function.
[00:03:55] And that identifier is a self reference to the function. So, we have access to that function from inside of itself which we'll talk about in a little bit why that can be important. But you need to keep in mind that a function declaration versus a function expression, one key difference there is what happens to the name identifier.
[00:04:13] Here are the name identifiers enclosed within itself, in our previous example, we saw that that bar identifier was added to the enclosing scope, okay? So there's a key difference. Another difference just to point out. This is kind of a smaller new ones one it's not gonna be a particularly huge deal from us to reprogram.
[00:04:31] But another example where the variable scoping may be different than what we expect is the catch clause of a tri catch condition. The catch clause declares a variable, there's not a var key there but it declares a variable and it's actually true that that variable is block scope to the catch clause itself.
[00:05:11] That all use the same variable err, they would complain that you had duplicate variable declarations which of course was never true. Since 1999, these have been block scopes. Since the very beginning they've always been block scoped. But the linters would complain about it, so I found myself doing silly stuff like err1, err2, err27 and so forth which is nonsense.
[00:05:34] [COUGH] Little side meta point there is you always need to be smarter than your own tools. If your tools don't know what they're doing, either find a better tool or just turn stuff off. I had to turn off that whole rule in the linter for five years or more because I didn't wanna complain about my catch clauses.
[00:05:50] So I didn't get the benefit of complaining about any other accidental duplicate declarations cuz they just weren't capable. I believe some of the newest revisions have fixed this but it may still be an issue with some linters.