This course has been updated! We now recommend you take the JavaScript: The Recent Parts course.
Transcript from the "Let vs. Var" Lesson
[00:00:03]
>> Kyle Simpson: What we wanna do now is turn our attention to things that I really do think we should be using more. These are more of the right parts of the Essex and the first thing I wanna talk about is block scoping. So, quickly all motivate block scoping I've covered these sorts of things, many of my other classes as well.
[00:00:23] So, I don't wanna keep repeating, but just wanna quickly motivate. Let's say I have a function called foo and there's some condition by which I want to swap those two, like for example the case where x is greater than y. Normally, you do something like this and then you'd say y = tmp; and we've used of our keyword inside of an if statement.
[00:00:47] Now, functionally meaning operationally the var keyword here is attaching a temp variable to the scope of foo. That's what people like to call hoisting. Hoisting's made up, that's I not a real thing, but that's the metaphor that we use to describe how lexical variables are attached to their lexical environments at compile time.
[00:01:08] So, it's hoisted to the scope of foo. But, why do we put it inside of the if statement? What is going on stylistically? Cuz this is the thing that people do, they'll put their var keywords in specific locations even though they know they actually behave as if they belong to the whole function.
[00:01:23] Well, what we're doing here is we're stylistically saying I want the tenth variable to belong only to that if statement. That's what it's for. Another example is when you have a piece of code like this and you do a for (var i) equals
>> Kyle Simpson: And then you have some code inside of the for loop.
[00:01:43] The var i here is going to be hoisted to the scope of foo, the i is available everywhere, but why do we put it on the for loop? The reason why, at least for most of us, the reason why we put it on the for loop is because we are stylistically signaling to the reader of this code i belong to the for loop.
[00:01:59] Don't use it before or after, even though you can, don't. Even though you can use temp elsewhere, don't, it's supposed to be used only for this if statement. These are the kinds of scenarios under which block scoping makes entirely sense. It makes complete sense in all of the languages that have ever had it and now JavaScript has it.
[00:02:19] Unfortunately, we can't just make the var key or blocks go because that would break a lot of old code. So, we had to add a new declared type. That declared type as the let keyword. In both of these cases, the let keyword will enforce the thing that we were already stylistically signaling.
[00:02:37] That's a really important point, don't miss what I just said. The let keyword in forces, at the compiler level, it enforces what we already stylistically signaled meaning I want temp to belong to the if statement now temp actually does belong to the if statement. If we try to use temp before or after, we're gonna get an error, if we try to use I outside of the for loop we're going to get an error.
[00:03:00] Because the let keyword is going to enforce that which we were already stylistically signaling. That is how I think you ought to approach this let keyword to enforce the things that you already stylistically signal. Does that mean that you ought to? Make all your voters in the less as some people are liking to say alright let is the new var there's a bunch of people on T-C 39 and this is a strong cult bandwagon that tells us lets the new var var is a code smell these are all blog post titles that have actually been written.
[00:03:34] So, should we be using the let keyword in places where it doesn't actually enforce some sort of block scoping, for example, at the top level of our function. You can, I don't think you should. This the place where I start to diverge from many of my peers who teach JavaScript and I respect their opinions but I think they're wrong on this part.
[00:03:56] They're missing the fact that the var keyword actually tells us importance stuff. The var keyword tells us when used in those positions, this is a variable that I intend to use across the whole function. The let keyword doesn't tell us that, its position tells us that but the let keyword itself does not visually signal what our intent is.
[00:04:16] If you use the var key word here it is now telling the reader of this code I know what I'm doing and I'm intending to use z everywhere. So, my personal take is you ought to use both let and var. Use vars in the places where you intend to use them across lots of scopes.
[00:04:33] Use lets in the places where you were already stylistically saying, I wanna contain it to this block. I think that's what it's good for, I don't believe in the let is the new var, I believe let and var. Let is the new helper to var, it helps you enforce the places where you wanted var to be block scoped all along.
[00:04:53] Yes.
>> Speaker 2: Question from the room. I've heard quote, only used let in places where you want the value to be mutable const everywhere else.
>> Kyle Simpson: We're gonna talk about constant a little bit. I'm not there yet, so we'll come back to that question. I'm just talking about how you decide and again, just like with the error function, I'm trying to present you the different cases here, cuz I want you to critically think as engineers I want you to analyze don't just follow some lint rule.
[00:05:24] Think about, which one is more appropriate? Which one communicates better? So, [COUGH] some other places where I think the var keyword is actually superior to the let keyword. Because there are places where I think that is true. Let's say that I had a line like this. Let's say that my line of my vars seen here.
[00:05:44] Was actually calling some other function like bar to get its value back, no big deal. I'm following the ES6 bandwagon. I put a let keyboard on it. Seems great, cuz that z is available to the whole thing. Now, maybe I'm the only one that's ever had a JavaScript error in their program but I get JavaScript errors in my programs, true confession.
[00:06:07] And when I get JavaScript there's one of the ways that I narrowed down those things of course, I try to use debugging tools but one of the ways that I narrow those things down is to try catches around stuff. So ,let's just say I've narrowed down that there is something happening with the statement I want to figure out if this is the place where the error is coming.
[00:06:24] So, I just casually come in and throw in my little try catch around this. Do you spot the problem? You see, what I did is I tried caught one error but then I created another error that's one of the big sins in all of programming whenever one fix, causes another problem.
[00:06:45] What's my another problem? My another problem is now z doesn't belong anywhere else. So, even if I figure out what's wrong here, I'm gonna get another error that says z is not divine. I'm like, what the hell? Z is clearly there. Crap, I forgot I had a lit keyword.
[00:06:59] So, whatever I'm doing that quick little like debugging I'm gonna have to remember in those places this thing can't just be trying. I need a var there,
>> Kyle Simpson: Or you're gonna do what some people say, which is, no, what you should have done is you never should have had those two together.
[00:07:16] You should have had the let z separate and then the z equals var and its own separate thing. So, you should add those separate there's your problem solved. This is the argument that's often made there's your problem solved. Now, what I'm gonna say is this, I think, this is personal taste, I think that one of the things that aids readability in my code Is when the declaration, the first usage of a variable is as close as possible to the declaration of that variable.
[00:07:48] By as close as possible, I prefer them to be on the same line. But if they can't be on the same line, I really want them to be as close as possible, okay. In this particular example, they're only separated by two or three lines no big deal. But as things go as our code evolves, you might start to see more separation between those.
[00:08:08] Could be five lines could be one hundred lines could be a thousand lines between the place where it was declared in the place where it was used. And as soon as you start to create more and more visual separation especially more than about three to five lines, now you have a visual readability problem because somebody's going to look at that line's equals bar.
[00:08:24] So, wait a minute, where does z come from? They have to go hunting for that let z. And then have to make sure that they don't cross any curly brace boundaries that they really found it exactly the same scope as the place that it was so I think you ought to use.
[00:08:38] Your variable declarations as close as possible to where you're gona use them the first time. That also means that if a variable is used in two very different places in the code. I'm gonna shock you and say, I think you ought to declare it twice. You ought to declared up here we use it and then you had to redeclare it a thousand lines later when you use it way down here.
[00:09:00] You can't do that with the let key word, you can't read declare with the let key word cuz you're gonna get an error. This is one of those places where in my opinion the var keyword shines because it allows me readability wise to put that little notation down there at the bottom.
[00:09:13] I am just reminding you the z is coming from this outer scope. So, I put the var z down there at the bottom. Another place where the shows up is in if statements. I regularly do this in my code. I'll have some kind of condition doesn't matter what the condition is and I have a whole bunch of variables that I create and initialize based upon this condition.
[00:09:32] So, I'll say var w = and var r = over and over and over again, and then I'll have an else, some other condition.
>> Kyle Simpson: And I'll have a different set of initializations for those. And maybe a whole different set of logic that's happening in that particular case.
[00:09:52] And then I'll do another else and I'll re-declare them again and again and again. Do you spot the problem values let's here?
>> Kyle Simpson: I'd be block scoping those if statements. These are not really if blocks in that sense and they're not really blocked. They're not really scopes in that sense.
[00:10:09] They're just collections of assignments that I want to conditionally happen. Don't go using some crazy set of turnaries stuff to do this, just use the var keyword. And if you want, go ahead and be super redundant put the barkeeper declaration also outside of the of statement because what you're trying to do really is not to write as few characters as possible to write as many characters as it takes to get your message across.
[00:10:34] Because you wanna communicate better, at least I hope that's what you want. That's what I'm trying to get out here. So, I think there are places operationally and stylistically that the var keyword in the let keyword can be used together. They have different purposes and one does not replace the other we have to use them together.