Transcript from the "Corner Cases: Booleans" Lesson
>> Kyle Simpson: Let's talk about == specifically with Booleans. This is another one of those really evil corner cases that you shouldn't do. This is something that you do a lot in code, and it's something you should definitely not do. It's something you do because you're used to doing this in other languages, and here, it's gonna get you into trouble.
[00:00:19] Okay, if you wanna check if you want to allow the Boolean coercion of an array to be true. In other words, you wanna say its truthy sort of construct. That is something that I'm okay with. Some people are not okay with that. But let's say that you do for the moment.
[00:00:35] There's one way of doing it, which is just just to do an if statement. Allow the if statement to invoke the to Boolean operation on the array, which, in this case, is a lookup that says the array is not on the table, so, therefore, it's true. That's a perfectly rational implicit to Boolean coercion.
>> Kyle Simpson: But if you try to get more clever and tricky with it and say, well, if it's truthy, then maybe what I ought to do is do a double equals with true. Well, now all of a sudden it doesn't work. And by the way, it wouldn't work with triple equals either.
[00:01:10] Cuz the comparison with a Boolean to an array is gonna go through a bunch of those corner cases, which we've already identified and we're about to re-identify. And also it's gonna be equal to false. So now you're gonna get the backwards of what you would intuitively expect. You think this thing is truthy, it is not double equal to true, but it is double equal to false.
[00:01:35] And there's no question that this is a gotcha. But before I even explain the gotcha, my answer to this is don't ever do a double, or even in that case, if you can avoid triple. But definitely, never do a double equals with true or a double equals with false.
[00:01:53] Because there's no scenario where you need to do a double equals with true or double equals with false when you could just do the to Boolean implicitly. There's no case where that or that is better. And there's a bunch of cases where it's worse, like this one, okay?
[00:02:11] So let's explain how the == true fails but the == false works. Same steps, same algorithm. We start with the top one. Of course if workshop students, we just do a to Boolean on it. Line 4, we check for the Boolean on it, and if it matches great, in this case it does, so we run that core branch.
[00:02:40] But what happens when we're trying to double equal it with true? Well, we have a non-primitive which need to became primitive, so it becomes empty string. We have an empty string and a true. These are not the same type, so they need to both become numbers. One of them becomes 0, which should have been NaN, the other one becomes 1.
[00:03:01] And those two numbers are definitely not equal, so we don't run that code branch. In the other code branch we do the exact same thing. We start off with workshop students = false. We get to a string = false, which becomes a 0 compared to a 0, and those 0s are equal to true.
[00:03:22] That's a nonsensical outcome to what was a nonsensical construct. You don't need to double equals to true, or double equals to false, allow the to Boolean to happen implicitly. So yet again, what I'm saying is that implicit is sometimes much better than explicit. In this case, the implicit doesn't have the gotcha and the explicit does.
>> Speaker 1: This is maybe too broad a question, too generic, but in other cases where you would go a step further and rather than running if workshop students. You would check if and then method all workshop students, checking the presence of .length to make sure it's a string or an array, or you're checking other type specific.
>> Kyle Simpson: So the scenario of this construct is I only wanna know whether it's set or not. And I know that it can either be unset or it can be set to an array, that was the mental construct of this scenario. So that would have been obvious by the rest of the surrounding code or at least hopefully obvious from the rest of the surrounding code.
[00:04:25] If we didn't know that, if we knew that it could be unset, or it could be set and it could be set to a variety of different things, maybe an array, maybe an object, maybe a string. Then we would wanna do some sort of deeper checking than just the to Boolean coercion.
[00:04:38] That might be the first step to check that it is actually set, and then the next check is to check something about its identity. And there's various ways that you could check it. You could use a type of operator, if that was appropriate. You could do what you're referring to, which is called duck typing, check to see if a method is on it, you could do an actual utility like array.isarray to check if it's in array.
[00:05:02] There's a variety of other things that you might wanna do if you cared to specifically know it was an array. But the setup I have here is that we would already know it's an array, cuz we already see line 1. It can either be set or it can be an array, and it can't be anything else in between.
[00:05:15] Does that make sense?
>> Speaker 1: Yeah, and I guess my question is if you would typically advise against packing it like duck typing into line 3 into that check? Trying to combine both.
>> Kyle Simpson: No, that's not what I'm saying. What I'm saying is I would do those if for some reason I couldn't restrict myself to know that it's either an unset or an array.
[00:05:35] I would prefer a smaller surface area with fewer necessary checks. I would prefer to design this code so that it's not so polymorphic. It's either unset entirely or it's an array. But if for some reason I couldn't design my code in that way, then I would put those extra checks into the if statement.
[00:05:52] Does that help?
>> Speaker 1: Yeah, that's great.
>> Kyle Simpson: Okay.