Deep JavaScript Foundations, v3

Cases of Coercion

Kyle Simpson

Kyle Simpson

You Don't Know JS
Deep JavaScript Foundations, v3

Check out a free preview of the full Deep JavaScript Foundations, v3 course

The "Cases of Coercion" Lesson is part of the full, Deep JavaScript Foundations, v3 course featured in this preview video. Here's what you'd learn in this lesson:

Kyle walks through typical situations where number to string, string to number, and any type to boolean coercions occur.


Transcript from the "Cases of Coercion" Lesson

>> Kyle Simpson: With those as our foundation, those abstract operations as our foundation it is now time for us to switch gears and really topic of coercion. And by the way as I said at the out set, this is going to require for you to get anything out of what I'm about to say over this next bit it's gonna require you to have an open mind.

Because you have been so programmed to believe that this is an evil buggy horrible part of JavaScript that you should avoid, that it's hard to see any value or merit out of this discussion. But I make it such a point of put it in the very top of this course because I think it's one of the most under valued and under looked that things in all of JavaScript.

So to start off with I know most of you follow that behavior and that advice that says, no I just avoid coercions. I just use the triple equals, I don't deal with types, not so much. Let's look at some examples where you're already doing coercion whether you realize it or not.

Any of you use the ES6 as of a few years ago, the template-literal strings? Yeah. I certainly use these all over the place. This is one of those slow burns. Cuz when it first came out, I didn't really care about this feature, and now I love this feature.

Might be on my top three favorite features. I use it all the time, especially in my colsole.log statements. I just use it everywhere and I love template strings. And if you drop in values into those expressions, that aren't already strings, probably, like all of you. Guess, what's happening there?

That number is getting coers to a string, implicitly, evil, you're already doing coercion, all of you, period. No matter what Doug Crawford said, you're doing coercion, you're relying upon coercion in your programs. And that's not a bad thing, that's a perfectly great thing. But under the covers, you should have the mental model that what's happening here is I'm taking a string, msg1, and adding it to a number.

>> Kyle Simpson: Now, why is that end up producing a coercion? Well, it's actually invoking another a little magical thing that programmers love to do which is we've got operator overloading. The plus operator is normally thought of is doing numerical operation. Thought? The spec says that if you use the plus operator with something that's a string, and here's an example that lot of you have probably done.

Add an empty string to a thing to turn it into a number. Did you ever stop to wonder how that worked? Well, it's because the specs says that the plus operator. If either one of them is a string, notice that or there, if either one of them is a string, the plus operator prefers string concatenation.

>> Kyle Simpson: Which means, if only one of them is a string, guess what's gonna happen to the other one? A two-string operation right there on 7.a. It's gonna call a two string abstract operation on it, and turn it in to a string with all of the weirdnesses in caveats there of.

When it's a well formed number, like the number 16, not such a big deal. But there's lots of corner cases on numbers, and lots of corner cases on other values, and you're just invoking these things happily, and not worrying at all, about the fact that you're using coercion.

No, I'm not here to tell you to stop using coercion, I'm here to tell you you're using coercion, so wouldn't it make sense for you to learn it? That's why we dive into this, okay? So, you may say, well, listen, I don't like to do those implicit coercions, I wanna be super explicit about it.

Okay, so, here's some crazy ways that you can be explicit about it, I just learned this one the other day. I never even considered that you could throw a value into an array, just the one value into an array, and then call dot join on it. And that actually ends up string it even though it does no string concatenation at all, the spec for that join first turns it into a string.

Don't do this that's a terrible idea, but you could if you wanna be super explicit about, you could say listen, I'm only doing string concatenations here. So I'm gonna be explicit about turning my number into a string. Here's some other ones that are maybe a little more well formed.

You might, for example, call the toString method. Okay, cool, the toString method at least on the label says what it's doing. It's gonna turn a number into a string so that's not too bad. There's a little weirdness here which is how are you calling a method on a primitive value?

Primitive values don't have methods. So you're actually already still doing implicit coercion here and we'll come back to that. If you don't wanna do any implicit coercion at all, basically your only option. Is to use that fundamental object without a new keyword string, and this is my preferred way of explicitly coercing that number to a string, the capital S string function is gonna do that for you.

So, if you're one of those that says hey, listen, all those implicit things, those are magical and we don't wanna do them, and you wanna be explicit about it, there's an example of being explicit about it. I'm not so sure that that's a great idea in all cases, but that's at least a way of being explicit.

All right, all right, all right, so string to, number to string all right, but what about the other way around? [LAUGH] You're already doing that too. Because all of you are dealing with web applications, or at least most of you are dealing with web applications which means you're dealing with user input from things like form elements.

Which means you're grabbing things as strings, and then you're just doing numeric stuff with them. When you throw that string value at the plus operation, like I'm doing here, guess what happens? Oops, we get a string concatenation. Instead of getting 17, we get the string 161. But okay, okay, I'll go ahead and force it to be a number.

Okay, there's two ways of forcing it to be a number one, this plus operator here. The unary plus operator, if you'll look in the spec for it. Guess what it invokes which abstract operation when we expect that turns out that the two number abstract operation, okay? Just making sure you're all the way, okay?

It invokes the two number operation, that's all it does. So here we're saying take that thing that's a string or whatever it is, and turn it into a number before we pass it in. If it's a well-formed numeric representation in string form, for example, you're gonna end up with good results here, like 17.

If it's empty, guess what you're gonna end up with?
>> Kyle Simpson: What's the empty string gonna become? Zero, it may not be what you want but it's gonna happen. So here's another example this kind of coercion happens all over the place. And my biggest frustration is that people don't deal with it and then just sort of slap a name badge on this is all I don't have to worry about types and coercion.

I'm good it's this, this is where bugs come from. Using tools that you don't understand how they work. Okay, so let me be more specific about it, even in the plus operator, cuz it might look a little weird. You can use the fundamental number function, okay. This is my preferred way.

If I'm gonna turn something into a number, I use the number function. We don't have a two number, so this is basically the most semantic way of telling the reader of code that you're gonna make a number out of something.
>> Kyle Simpson: If you use a minus operator for example, if any of you get too sarcastic with me I'm gonna kick you up.

If you use the minus operator that one is only defined for numbers. That it's not overloaded for string, it wouldn't make any sense to subtract one string from another. So that minus operator up there, is gonna do what?
>> Kyle Simpson: Come on? Two number, okay? It's gonna invoke that two number abstract operation.

These are all things that are happening in your programs in various different ways. And I think it would be a good idea for us to call these things out and be a lot more aware of incognito of it intentionally about.
>> Kyle Simpson: Okay, okay, okay, strings and numbers are always work things but you know what I never do, because I never mess around with coercion my Boolean, right?

Cuz I never write if statements that use non-Booleans in the if class. Any of you use like checking to see if a string is non-empty to see whether it's truthy or not? Extremely common practice, guess what that's called coercion. Okay, and guess what? All of the weird corner cases of coercion Booleans are in a fact, even with your little simple if statements they're in a fact.

Matter of fact, I would say there are more corner cases with boolean, maybe than any other premier of type or kinds of wearnesses that we're gonna get into here as we go So that empty string, if students input that value as an empty that's gonna be falsy, alright?

But what if that string has just a bunch of white space in it? Now it's gonna be truthy, right? It's not a valid string that you care about because it's got a bunch of white space in it but all of a sudden it's going to be truthy. Corner cases even with our Boolean.

Another favorite one, people love to use the numeric coercion of a number to either a zero or a non zero for truthy or falsy, right? So if my length is zero then it becomes false and if my length is anything non zero then it becomes true. Because it's not one of the zeros, will have to rely up on that.

Except what happens when it's NaN.
>> Kyle Simpson: Okay, there's all kinds of corner cases in all of these coercions. So if you're in the habit of using some of these and not using others, I mean I hate to call this out but it sort of hypocritical to say, I used this form or magic but I don't like that form of magic.

I don't know if we should use the magic at all, I think we should learn it, use it, and then it's not magical at all. Once you learn it, you're doing something intentional, and you're communicating your intent to other people. That does not mean that implicitness is always bad.

As a matter of fact, implicitness can be very useful. It just simply means we have to be very careful and intentional. So you might say well I like to turn all of mine into explicit booleans. So you might use that. Double negate up there on line one. Tha's telling it, become a boolean.

I don't have it on this slide, but you could also use the fundamental capital B Boolean. That's what I prefer to do. Just like straying a number, I prefer to use capital B Boolean. But with numbers, it's better instead of relying upon that numeric coercion, use something like greater than zero, if that's what you mean.

Not only does it protect you from some of those corner cases, not all but some. It protects you from some of those corner cases but it is also more semantic. Because you are saying here, keep looping while the length is greater than zero, instead of keep looping while the length is truthy.

What does that even mean? So don't be clever just to save a couple of characters, be more explicit about it in the places where explicitness is more communicative.
>> Kyle Simpson: We already covered some of this. I jumped ahead in my slides. But the Boolean of an empty string is false.

The Boolean of a non-empty string is true, and that's certainly gonna be a gotcha.
>> Kyle Simpson: Okay, the Boolean tests for undefined and null, we know that both of those are on the list. I like to treat null and undefined as indistinguishable values. Wherever possible. It's not always possible to treat them as indistinguishable.

But where possible, I like to do so, and cohesion actually is very helpful for that. But with respect to Boolean since we know that they're both forcy, if the test that we're asking for is has this thing been set or not, which we do often. Is this thing been set on object or is it still onset.

All right, for me, that's a perfectly reasonable in placing Boolean coercion that I'm okay with. I don't like to impose the coerce and empty strain the false and not empty strain the true. I don't like to impose the coerce numbers to true or false but I am perfectly happy with either saying it's no or undefined, meaning it's unsaid, and that's falsely or it's been set to something like an object.

And then it's tricky and I use that all the all over the place. So in my particular opinion, I think it's okay, to use the implicit to Boolean coercion when we're specifically talking about either an object or null undefined that decision making. But the numbers and the strings, since they have so many corner cases, I don't think that that implicit coercion carries its own weight.

>> Kyle Simpson: I'm less trying to be prescriptive here about exactly how you should do it, and more trying to get you to think like JavaScript. And make your own determinations for where do I draw these lines.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now