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

The "toString" 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 discusses the behavior of the abstract operation toString.


Transcript from the "toString" Lesson

>> Kyle Simpson: So let's talk then about the next abstract operation. It's called toString. The toString abstract operation does what it sounds like. It's very descriptive on the label. It takes any value and gives us the representation of that value in string form. And almost every value that you can imagine has at least some kind of representation in string form.

By the way in the parentheses I'm noting the actual spec sections as they exist currently in the version at this moment which is ES2018. They voted on the ES2019 spec and it'll come out a little bit later this year. Hopefully most of these section numbers won't change but those are for the ES2018 specs.

Okay so the toString opperation. Boiling down a bunch of details let me just show you some examples of things and what they end up producing as a string representation. And for the most part these are exactly what you'd expect. If you had a null value and you ended up doing that toString abstract operation in some way, you'd get quote null.

Same thing with undefined, true false, floating point numbers, even the zero. Things get a little strange when we look at the negative zero, remember that. We already saw that it lies, the toString operation for negative zero lies and produces a quote, zero. So that's one of the corner cases and we'll talk more about corner cases in a bit.

All right so if we call toString on an object remember it's going to invoke the toPrimitive with the string hint. So what's that going to give us? Remember that's gonna end up calling toString first and if it's present and then it's going to use valueOf. That's the order that it does.

So what's that gonna look like on some particular object? Well, if it's an array, for example, arrays have a default toString, which serializes the representation of the array. It's a bit of a strange serialization, in my opinion, because they're leaving off the brackets. So if you serialized a empty array, you get an empty string.

I think that was a really dumb decision. I don't know why they left off the brackets. Because it turns out, there's a bunch of things that can serialize to strings. So how am I supposed to know whether it was an empty array? But nevertheless, this is how it works.

The built-in toString on arrays leaves off the brackets. If we have an array with some contents in it, it'll show those contents unless they're null and undefined. And this is even weirder, the toString definition for this. I actually was just reading the spec the other day and I was like why on earth they do this, nulls and undefines, when they show up in arrays just get left out.

I mean they're there presently. You can see there's a comma there. They're there presently in terms of position, but they're not represented as nulls and undefines the way null and undefine when toStrings do. In my opinion, a bizarre inconsistency. Essentially, array to stringification is like maybe you could use it in the dev console but I would never use something like this in my program because all these weird corner cases of its behavior.

>> Kyle Simpson: What about on objects? I'm sure you've all seen the bracket object object thing which is like, what on earth is that? The default toString on the object of prototype is to do that whole bracket thing. And this, let me just rant for just a micro moment here, why on earth did they leave off the square brackets for arrays and put the square brackets on objects?

Somebody explain that to me, what on earth. Bonkers. Okay but back to reality for a moment. It does the square brackets, it does a lower case object and then it puts in this thing which is called the string tag. And it turns out you can actually override the string tag for any of your own custom objects using an ES6 symbol.

You can, it's called toString tag and you can change it. So you could change it from saying Object there in that string to saying my favorite number, or whatever you want it to say. That's a meta programming thing but it is possible to do. So that Object there is the default string tag for all default objects.

And then the toString method takes that string tag and wraps this other junk around it. If you over ride the toString method, you can completely control what you want the stringtification of your object to look like. In this case, I'm making it turn, return just a string X.

I have used this by the way, I have defined a toString method, but I've defined it as a getter so that it can be dynamically returned in the string tag. I've defined this in such a way so that, on an object, and I don't do this all the time.

But if I'm trying to understand what's in the context of an object, object Object is not helpful to me. But you can override it, and tell it to JSON-stringify the object and print those results, and that is much nicer. So you can override a toString, or the string tag, to help you in the dev console.

But again, this is not the sort of metaprogramming I would typically do much in my programs.

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