Check out a free preview of the full Deep JavaScript Foundations course:
The "Primitive Types Introduction" Lesson is part of the full, Deep JavaScript Foundations course featured in this preview video. Here's what you'd learn in this lesson:

While reviewing the built-in types: undefined, string, number, boolean, and object, Kyle notes that the symbol "type" is added in ES6 and "function" is a subtype of the "object" type.

Get Unlimited Access Now

Transcript from the "Primitive Types Introduction" Lesson

[00:00:00]
>> Kyle Simpson: So let's jump into primitive types. The JavaScript spec lists out the following primitive types, undefined, string, number, boolean, object. Now these five are there. And to be honest with you there's a sixth one that's listed that I'm not putting here on the list because it's ES6 and beyond.

[00:00:19] And also because it's a primitive type that nobody even really cares about. At least, I don't have much use for the symbol primitive type. It was added as an actual primitive and we're not gonna really cover that in this course. But there is a symbol there. But there's a couple of others that I'll put on the list, function and null.

[00:00:35] It is definitely true that null is a real primitive type. But what's interesting about function is that function, though we may think of it as a type, as a value type, it certainly has a set of expected behaviors. By that pragmatic definition, it is a type, right? Because the aesthetics of us working with a code, we can do something different with a function than we can with any other value type.

[00:00:58] We can call it. But actually, function is not a real first class primitive type, actually, it's a subtype of the object type. Matter of fact, it's referred to as a callable object, that's interesting.
>> Kyle Simpson: So you could say this is seven or six types, it's really officially these six types plus the symbol type that I've left off.

[00:01:16] [COUGH] That's what we wanna focus on with these primitive types. I've highlighted null specifically because there's a bug with that type that we'll look at in just a moment. But as I was saying earlier, it is the values that have types, the values that are in these different classifications.

[00:01:33] They're the things that they adopt or inherit these expected behaviors. Something we can do with a number that we can't do with a Boolean, for example, okay? So when I use the typeof operator, for example, and I do typeof foo, that looks like I'm asking, what is the type of the variable?

[00:01:50] But actually what I'm asking is, what is the type of the value that is currently in that variable? That's what the typeof operator's doing. Because a variable can hold any type at any time, we have that freedom. You may like that freedom, you may not like that freedom.

[00:02:04] If you don't, choose Typescript. But JavaScript itself offers us that freedom. And some of us don't just do that because we like to write poorly constructed code. Some of us prefer that freedom. I prefer to have the freedom to choose what type I put into a variable. I don't prefer to do silly things like, if I have a value that's gonna go through three different conversions.

[00:02:28] I have to come up with three different variables, and then come up with some kind of naming convention. Like, lowercase b is the first character to say that it's a boolean, and lowercase i to say it's an integer, or whatever. Those kinds of things, to me, are silly.

[00:02:40] I don't like those kinds of conventions, so I prefer if it's going to go through multiple steps, use the same variable. Cuz I am describing the same thing, just different representations, so that's my way of thinking about stuff. Typescript's great if you like that, go to the Typescript world.

[00:02:54] They're going to enforce that a variable needs to hold the same value type at all times. But you notice something interesting about this typeof foo here, there is no foo variable. I didn't declare a foo there. The typeof operator is special privileged and to my knowledge the only specially privileged mechanism in the entire language which is able to deal with a variable that is non-existent and not throw an error.

[00:03:21] Every other mechanism, if you refer to a variable and it doesn't exist, you are gonna get some kind of an error. But here are the typeof operator we're referring to a variable that has not been declared and yet we get undefined. Which is interesting because this is definitely not an undefined variable.

[00:03:38] This is an undeclared variable. But there's a big difference between defined and declared. Declared means physically exists in some scope. Defined means has some value, has some useful non-empty value in it, okay? And JavaScript is not doing us any favors by conflating these two, because that just makes things more confusing.

[00:04:00] So I wish the typeof foo here would give us undeclared, but unfortunately gives us undefined exactly the same as if we had an existent variable with no value in it at that time. We get the same value that's called undefined. This was designed to be more forgiving of us accessing variables, like for example, global variables.

[00:04:21] We're doing feature checks through things and the variable has not been defined, we don't wanna throw errors. We don't have to wrap that stuff and try catch, so they're trying to be more forgiving about it. But what they fail to do is give it a different return value so that we can distinguish those two cases, because they very much are different.

[00:04:38] Matter of fact, there will be error messages that we talk about later when we get into scope and closure. There's error messages that will say things like, foo is not defined. And you think, well, okay, then foo is undefined. Cuz is not defined and undefined sure sound like they're saying the same thing, right?

[00:04:54] No, foo is not defined is the JavaScript speak for foo is not declared. So you see why there's a problem if we use undefined as a conflation of undeclared. All right well typeof "foo" is pretty straightforward. We get "string", "number", "boolean", "object". You notice that the type of operator always returns one of these six values.

[00:05:16] The seventh value being the symbol type that we are not covering here. So "undefined", string, number, boolean object and function, there are always string values that come back from the typeof operator. This is an invariant of this operator. It can never actually return undefined, it always would return "undefined".

[00:05:33] I've seen many many blog posts and books somehow made it through editing where somebody will something like typeof x === undefined. And that's nonsense because the type of operator will never actually return that value. It will always return a string, okay?
>> Kyle Simpson: But there's a notable omission from this list, and it's the null, why?

[00:05:53] Well if we say typeof null, we get back "object", instead of, as we may had expect, "null". Now I had this grand unified theory at one time of why this was, that nulls, the history of null was that it was really designed to zero out object pointer. So it's kind of like null is this special global constant object thing or whatever.

[00:06:15] That's the theory that I use to espouse. And one day I was tweeting about that, this is years back. But I was tweeting about that and it's kinda funny because it's almost like if you tweet about JavaScript it's kind of like the bat signal for Brandon Ike. Because to my knowledge he didn't follow me on Twitter at the time, but he just showed up in my Twitter mentions.

[00:06:34] Here's me just off in random land, tweeting about JavaScript, and he shows up and he's like, no, no, no, no, no, that's crazy, it's just a bug. So it turns out typeof null returning "object" is a bug. There's a question online?
>> Off screen: Yeah, they were just asking if you could clear up, again, the difference between undefined and undeclared.

[00:06:52]
>> Kyle Simpson: Yeah, we will go over this again, so if you've missed that, don't worry. But undefined and undeclared, undefined means the variable exists, but right now it doesn't have any value, so it has the undefined value in is place. Kinda like the vacuum of space, if you will.

[00:07:07] If you take everything else out, it's undefined, okay? That is an actual value, and that's when a variable exists but at the moment has no value. Undeclared means you literally never declared it in any scope that that piece of code has access to. So in that previous slide when I said typeof foo and there was no var foo in scope, foo in that case was an undeclared variable.

[00:07:28] As opposed to a declared variable that at the moment has no value. So that's the difference between undefined and undeclared. So here we have a var foo that has been declared, and I say typeof foo. What am I gonna get back?
>> Off screen: Undefined.
>> Kyle Simpson: "Undefined", I'm gonna be super picky here, okay?

[00:07:46] The string value undefined, "undefined", that's what I'm gonna get back. Now what about line 4? Don't get tricked by line 4, var bar = typeof bar. At the moment that we run typeof bar, does bar exist?
>> Kyle Simpson: We'll get into that when we talk about scope and the compiler and all that stuff.

[00:08:08] Yes, it absolutely exists. What is its current value? At that moment, it's still undefined. So when I say typeof bar, what's gonna go into the bar variable that we see in line 5? What is the value in bar gonna be at that point? It's gonna be "undefined". And so then on line 6 when I say typeof bar, what am I gonna get?

[00:08:27] "String", same thing with line 8. What's line 8 gonna return?
>> Off screen: String.
>> Kyle Simpson: "String", because the typeof 2 is "number" and the typeof "number" is "string", okay?