Transcript from the "Challenge 2: Solution" Lesson
>> Kyle Simpson: All right, let's talk about exercise two. Hopefully, you got a chance to read through the readme. And you'll notice that the readme mentions several things that we should be looking for. The first of which was, are there anonymous function expressions that ought to be name function expressions?
[00:00:15] So to call your attention to one such example, in EX2.js we have this handle click function that's being declared as a variable, and then added to the click handler here. Now in general, I would say, that one probably should go ahead and be its own function declaration, cuz it's got several lines of code to it, 15 lines of code.
[00:00:39] Typically I'd go into make that a function declaration. But there was a different reason why I chose not to make it a function declaration. If you saw in the solution file, I chose to block scope this one. And it's because basically this function really only exists for one particular purpose and that is, this line work gets attached.
[00:00:58] So I go ahead and create it as a block scoped variable. So I make an explicit block and declare it. I set it to this variable, and then I give it a name. And you notice that here the name is different. Here the name makes more sense, because I'm describing exactly what it's doing.
[00:01:12] So there's actually different purposes. The submitNewWorkEntry tells me what this thing is gonna do. HandleClick is more appropriate to describe what context it's being used in. It's being used as a click handler. So there's an example of using different names, between the variable it's assigned to and the function expression name.
[00:01:32] That's an example where the different names were more appropriate.
>> Speaker 2: Is there any reason why you didn't declare handleClick on line 11 with let?
>> Kyle Simpson: I typically, in my style, I typically like to declare my variable separate, especially cuz I might be doing multiple variables. I just put them in one let statement on that first line, and then use them on the next few lines, rather than adding them to the same declaration.
>> Kyle Simpson: Okay, another example of using the block scoping to our advantage. It may not have jumped out at you as terribly obvious, but in this ad project function. We create a project ID, but we only use it on the very next line of that code. The rest of that function, it's only three or four lines, but the rest of that function does not need the project ID variable.
[00:02:23] So from a future-proofing perspective, since I'm only using it in that one localized position, I can go ahead project ID be a blocked scope variable. So here's an explicit block and you'll notice I kept project entry data as a regular variable on the outside that will get set from the inside, similar to what we do with for loops.
[00:02:43] But now I've gone ahead and declared project ID to be a blocked scope variable. It's set and then used and then it goes away, because it's all ready been captured into what it needs. Even though this a small example of only a few lines of code, it's an example of the mindset to approach, ask yourself, where does a variable need to exist?
[00:03:04] And there's a principle in software engineering called the principle of least privilege, the principle of least exposure, which says, keep something as hidden as private as necessary. Only expose it where minimally necessary. So here I'm monitoring that by saying, let's only make it accessible to those couple of lines of code.
[00:03:21] Few other places where I used the let, I put them into for loops like for example here, we have a let on that for loop. And then here's one last example, you'll notice in the previous code, in the EX2 unfixed version of the code, I did VAR entry index there on line 115.
[00:03:47] And I set that entry index or it just got incremented as it goes through the for loop. That entry index is then used outside of the for loop down here on line 122 and elsewhere. So I'm using a variable that's being updated by the for loop outside of the for loop.
[00:04:04] As I said earlier in my lecture, that's typically not a style that I would recommend you doing. Of course it works, but it's not a style I'd recommend because it can be a little bit more confusing to somebody. Where does it come from, and what value is it gonna have?
[00:04:16] So I wanted to be a bit more explicit about it, so what I did was use block scoping. I made an entry index that is block scope, cuz it's only needed for this one block of scope. And I used a let on the for loop to create an i that only exists for the purpose of the for loop.
[00:04:32] And you'll notice that when I decided to break the for loop, I went ahead and captured the value of i into the entry index and then used it. So I kept the i for the purposes of the for loop. I kept the entry index for the purposes of this if statement, rather than making the let in the if statement and made an explicit block of scope for it.
>> Kyle Simpson: [COUGH] One last thing mentioned in the readme. It asks, do we need some consts? Well, it turns out there were a couple of places where I was doing variable declarations before, in particular these two template variables. Both of those are templates that are not ever gonna change throughout the course of the program.
[00:05:18] And they're already immutable values, cuz strings are immutable values. So it made sense to go ahead and declare those as const. So I went ahead and declared them as conts. And while we're at it, there were a couple different literals that I was using in the program. Prior, we were in the validate function, where is that?
>> Kyle Simpson: In the validate function, you notice I'm using different literals here like hard coded the number 5, 600 that sort of thing. I'm hard coding some of these literal into the program. What I decided to do was go ahead and pull those out as separate const declarations, and then use those variables.
[00:05:59] That does a couple of different things. First off, at the beginning of reading this piece of code, I can see where those are and if I need to change them I can change them in one spot. But secondly, those names if I give them good useful names, those names now make those codes more understandable.
[00:06:14] So here if I ask description link less than five, you don't really know exactly what five is. It just looks like a magic, the number that shows up. But now when I've given it the name minWorkDescriptionLength on line 33, now it's more clear this thing is specifically describing the validation rule specifically describing the length can't be less than the minimum length for the work description.
[00:06:39] Same thing with greater than maxWorkTime on line 38. So using those constants and giving them good useful names, actually make those places in the code more readable
>> Kyle Simpson: So that's how I chose to use let, const, and explicit block scoping to improve the code. We didn't add any new features, but we just improved the code with that.
[00:06:59] Any questions about how you approached it, or things you might have tried to do differently?
>> Speaker 2: I'm still unsure how you decide to use let?
>> Kyle Simpson: So I think this is the best example. Prior to the change, if we compare these two.
>> Kyle Simpson: Sorry, here we go. Prior to this change you'll notice I just make project ID as a var.
[00:07:35] Now what I'm signalling there is project ID is gonna be used to cross the entire function. It's not really terribly relevant that the functions only six lines of code, because it could be 20, or 50, or 100 lines. But I'm saying to the reader of the code, almost subconsciously, projectId is something that's gonna be used in a bunch of places, so know about it here, right?
[00:07:56] But in reality, that projectId is only used on the very next line. It's used right here on line 46. It's not used in 47 through 50. So that's an example of a localized variable. It's only used in in one place. And when you have a localized variable, it can be more helpful to block scope that.
[00:08:14] Not only to visually separate it, so you're saying this thing only exist for this one purpose. It's almost like it's a temporary variable. [COUGH] So not only to visually separate it, but also to enforce that people don't reuse a variable in different places if you don't want them to.
[00:08:29] I think that question is saying like here, are these curly braces necessary? Well yes, they're absolutely necessary. They're creating a block iIn which the led declarations scopes itself. If I took the curly brace out, that a projectId would belong to the entire function. So the curly braces are not like unnecessary parenthesis for example.
[00:08:51] They are real. They are creating a block for which I am now scoping projectId to it. So hopefully that answers the question. Yes?
>> Speaker 3: In that, if you did pull off curly braces in that example is there any difference between let and var within that scope?
>> Kyle Simpson: There are difference between let and var.
[00:09:12] One example is that lets can't be re-declared. So if you wanted to re-declare it 100 lines later in a longer function, you can't do that with let, but you can with var.
>> Speaker 3: Okay.
>> Kyle Simpson: But stylistically, using a let there and actually block scoping it, to me creates a more confusing signal.
[00:09:32] Or at least, if it's not more confusing it's at least less information than what we give with the var.