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

Kyle goes over native functions or "natives," which are built-in JavaScript functions and takes questions from students.

Get Unlimited Access Now

Transcript from the "Native Functions" Lesson

[00:00:00]
>> Kyle Simpson: Let's turn our attention to Natives. I've listed out for you, and you notice that they all have capital letters here. I've listed out for you the built in Natives. There are actually more than these, but these are the ones we'll pay attention to. These might look familiar because these might look to you like these are the built in types that you see in Java, for example, like capital S String looks like the capital S String class that's built in to Java.

[00:00:23] So it'd be tempting to think of these as Native Types, many people will refer to them as Native Types. They're not actually dealt with as types from the perspective of the spec, if you read the specification for JavaScript. It does talk about these and as a matter of fact, calling them natives is not even fully agreed upon.

[00:00:42] That's just kind of a term of art that people seem to have settled upon. But I've heard people have different answers as to what these should even be called. So they're not really types. They're not really objects, although in a sense all functions are objects, so they're kind of objects.

[00:00:59] But calling them native objects could sound a little bit strange. The capital O Objects is definitely used more like an object than a function but it's not really proper call them. You'll typically think of them in the context of what you did with Java or you put the new key word in front of them and called as a constructor.

[00:01:15] So you might think of these as native constructors. But I really think the most appropriate way to approach this is that you virtually in almost all of these cases, you will never want to call them with the new keyword. As a matter of fact, most of these cases, you'll wanna call them as regular functions.

[00:01:31] So I think maybe we should just call them the Native Functions. And capital N Native, we don't mean native like built in. That's a special thing to distinguish it from the primitives, okay? So what are these things? Well, used as constructors, they definitely produce a representation of the value that is similar to the primitive equivalent.

[00:01:53] So if I called new, capital S String, I'm gonna get a thing that seems like it's related to the actual primitive string, but they're not really the same. They're just a different representation, a matter of fact, kind of an object wrap around. Same thing with numbers, same thing with Boolean.

[00:02:07] Now some of these act as, there are differences here, there's not a lot of consistency. So some of these will act as constructors, meaning you have to call them with new or if you don't, they'll behave differently. Some of them will act as constructors regardless of whether you call them with new.

[00:02:23] Like the Function will produce a dynamic function, regardless of whether you use the new keyword with it. Object will do a different thing. Array doesn't need the new keyword. RegExp doesn't need the new keyword. So some of these require the keyword, and some of them don't, so there's some weird inconsistency, but I think it's more appropriate to think of using them as functions.

[00:02:44] So if we compare, for example, what happens when we call newString and pass in some value, when we ask, what is foo, there on line too, turns out that foo, if we represent it, if you tried that in your console, it's actually gonna be represented as an object.

[00:03:01] It'll be represented as on object that has properties like zero, the value f, and one with value o, and two with the value. It presents itself almost like an array-like object. And it has this weird special built-in properties like bracket, bracket, primitive value, I know there are strange things like that.

[00:03:21] Another battle that I fought with the browser of vendors by the way because the way they represent these values in the developer console is in large part going to contribute to whether or not you understand what you're doing or whether you're confused as a developer. And Firefox used to be the worst offender of this, they would represent string object as almost identical to the string primitive, the only difference being that the string object they print it in italics.

[00:03:46] And I'm like, are you kidding me? You expect developers to distinguish in the font between italic and non-italic and that's how they know whether it's an object or a primitive? That is just deliberately asking for people to be confused. Finally they changed that. They actually changed it according to my recommendations.

[00:04:06] I'm still waiting on Chrome to catch up with it. Cuz Chrome's representation is bad in a different sort of way, okay? But these are objects. They're not primitive, that's the take away here. And if you do type of food, you're going to get quote object. Cuz it's a real object, it's not some special kind of string thing.

[00:04:21] The way to think about that is it's a wrapper object around the primitive string value, the one that we passed in quote foo. Now, you'll notice on line 7, I called the String function without the new keyword. The String function, when used as a function rather that used as a constructor, it does something very different.

[00:04:43] Instead of constructing an object wrapper around a value, it actually coerces whatever you pass in to that primitive value type. Capital S String used as a function without the new keyword will take whatever you pass in, even something like the number 42, and coerce it to a primitive string.

[00:05:02] So it would say quote, 42, would be the output. That is a vastly more useful mechanism to us than creating these weird string object things that nobody actually wants to deal with in JavaScript anyway. So my recommendation specifically for string number in Boolean, use them as functions specifically for coercion.

[00:05:21] Don't use them as constructors with the new keyword.
>> Kyle Simpson: Line 10 would produce a number object wrapped around the 37 value. That's strange, okay? Examples of the strangeness that you might get if you represent these things as objects like a Java developer would typically do. If you said number of zero, zero as a primitive value is falsy, zero as a number object is truthy.

[00:05:54] You're setting your self up for failure there. Same thing with Boolean, false as a Boolean primitive, is falsy, false as a Boolean object is truthy, okay? Don't construct these objects, there's just no reason for them. They will set landmines, not only for yourself, for your future self but also your other teammates, okay?

[00:06:20]
>> Kyle Simpson: Array, the Array constructor has its own set of problems, but the nice thing about array is that there is a literal syntax that we can use instead, the square brackets that we see on line 5. The literal syntax is vastly preferred to the constructor form. Use the literal form wherever possible, don't use the constructor form.

[00:06:42] There's a got you with this particular constructor, which is if I said new Array 42, many people would assume that I would then get an array that was pre-sized, I mean that was set with the value 42 in it.
>> Kyle Simpson: Because I passed in array 1, 2, 3, and I got an array of 1, 2, 3 so they would think, if I pass in a single value, unfortunately, the Array constructor is overloaded.

[00:07:05] Overloading is never a good idea in software design but it's overloaded here. To say if you pass in a number, and there's only one of them, then that number is considered to be the length of the new array that you wanna create. So we'd actually get an empty array, presize to length 42.

[00:07:23] But that's not even the craziest part. The craziest part, the part that is really, legitimately a W-T-F of JavaScript, is that we have this notion of what's called a sparse array. If I create an array that is empty and then I set it's length, I literally say array dot length equals, and I say 42.

[00:07:46] It will present itself as being an array that has 42 slots in it, but only from the perspective of how the console deals with it. If you tried to loop over its values with something like .map, it's not gonna have any values to loop over. They're like phantom, fake slots or so-called empty slots.

[00:08:07] This is literally the worst design I've ever seen in any programming! Like, I've seen a lot of crazy, crappy stuff, but to create a value that has phantom locations in it. It's like a giant neon sign that says I'm trying to confuse you, I'm trying to make you trip up, I'm trying to create pity failure design.

[00:08:29] Never, ever, ever design an array and intentionally create empty slots, and that's what you do when you do array, parenthesis, and some number. Our notion is, for performance, I wanna presize my array, right? That's nonsense, JavaScript does not preallocate 42 units of memory for your array. It literally creates an empty array which JavaScript typically represents as linked list, by the way, and then it just arbitrarily sets the length property to 42, thereby making these phantom slots appear that they're there and they're not really there.

[00:09:04] So don't ever do it under any circumstances cuz there's no performance benefit, and there's a ton of confusion coming around it. So just don't use the constructor form for array, use the literal, it's always more preferable. Object, Object as a function will take value and try to coarse it to its object representation.

[00:09:28] There are some nuances around it. I don't recommend using object very often, but new object creates an object instance exactly the same as the curly brace instance. The curly brace literal form. The literal form is shorter, more straight forward, and technically slightly more efficient, cuz it's statically analyzable where the imperative property assignment of line 8, 9, and 10 is not.

[00:09:51] So the literal form here yet again is gonna be more optimizable by the engine because it's the declarative form as opposed to the imperative form on lines 7 through 10. So again prefer the literal syntax over the imperative syntax of the constructor.
>> Speaker 2: So the benefit here is really statics and not necessarily performance, right?

[00:10:14] It's just being a little bit more better in communication.
>> Kyle Simpson: I mean there is a performance issue to be gained because we can say, okay, great, I know that the engine either already or eventually, can more statically analyzed a literal and know what to do with it. For example, array literal, it literally can see at the parsing stage how many elements you've added, so it goes ahead and pre-reserves that amount and doesn't have to like add it or whatever.

[00:10:42] It just knows, I'm gonna need this many, and then it puts all of them in. So because it's statically analyzable, it's more efficient that way. Now, we're talking about microseconds, but it is more efficient because it's a declarative syntax the compiler can recognize, as opposed to line 8, 9, and 10, it's just figuring that out line by line by line.

[00:11:00] So it has to keep growing the object every time, right? So there is a performance aspect, but really, this is more about code communication even than performance. The literal on line 10 and the literal on line 5 communicate more clearly my intent. I declare literal as opposed to imperative.

[00:11:21]
>> Kyle Simpson: There are some where you're gonna want the new keyword, specifically for a RegEx. You're gonna need to use the new keyword if you want to dynamically create a regular expression. Now, you should prefer the literal syntax if at all possible, because the literal syntax gets compiled once.

[00:11:42] It doesn't get rerun at run time whereas the dynamic regular expression has to get rerun every time that code runs. So you should prefer the literal from performance and declarative coding reasons, but there are sometimes when your patter needs to be dynamic. Part of the pattern is a value in your program that you programmatically, logically decided, then you're gonna need the regular expression constructor form, okay?

[00:12:08] So it's entirely okay to use that if you have to, prefer the literal syntax if possible. Dates on the other hand have no literal, this I think is a huge mistake, it's a missing gap in the design of JavaScript. We should have a date literal. Dates are pretty important.

[00:12:22] And we should come up with a good date literal that everybody can agree on, make it the UTC, one of those ISO standards or whatever, and just agree upon it. But we don't have that right now, [COUGH] right? There are some people that are talking about adding it, but we don't have that right now.

[00:12:35] So if you wanna construct the date timestamp, you have to use the constructor form of the date constructor, you have to say new date. That's gonna construct a new by default with no arguments, it's going to construct a timestamp that represents this exact moment. It's kind of the Unix timestamp milliseconds thing, right?

[00:12:53] Now, I will say most of the time that you construct a data object, it's because you wanna get the current timestamp of right now. And if you get a date object, you then have to extract that number timestamp from it by calling a function or coercing it, we'll talk about that later.

[00:13:12] There's a much better way of getting that, and it's called Date.now. It's a static function, gives you that timestamp. So you really should prefer not to ever construct the data instances if possible. Most of the time you can get away with not needing to construct a date instance, but if you do need to, you're gonna have to use the new constructor to do it.

[00:13:32] Yeah.
>> Speaker 2: So that example on the previous slide with the curly braces declaring array, if you try to and for some reason doesn't come back as an array in the console it's more of an object-
>> Kyle Simpson: Which one? The curly braces do an object, the square brackets do an array.

[00:13:48]
>> Speaker 2: Okay, that's good.
>> Kyle Simpson: So if you do curly braces that's an object, square brackets array. So question here from Craig. What advantage is a date library like Moment JS? I wouldn't do any date stuff in JavaScript without a good date library. And moment JS just happens to be a really good one, I know when-

[00:14:05]
>> Speaker 2: It's pretty big though, so there's microlibraries that are, you know won't upload your project so much.
>> Kyle Simpson: Yeah.
>> Speaker 2: But moment's Craig, cuz it's robust, you can do time zones, you can do time zone math, you can add a few days, you can subtract, you can compare.

[00:14:21]
>> Kyle Simpson: It's true, Moment has a lot of capability to it. I know one of the maintainers of Moment is actually working on getting some of that stuff just built into JavaScript. So we don't need such heavy libraries to do it. Dates are a big gap in the behavior of JavaScript, stuff we need the standard library to just grow that capability.