When Primitives Behave Like Objects

by kirupa   |   31 March 2014

In the earlier Strings tutorial and less so in the Of Pizza, Types, Primitives, and Objects tutorial, you got a sneak peek at something that is probably pretty confusing. I've stated many times that primitives are very plain and simple. Unlike Objects, they don't contain properties that allow you to fiddle with their values in interesting (or boring) ways. Yet, as clearly demonstrated by all the stuff you can do with strings, your primitives seem to have a mysterious dark side to them:

var greeting = "Hi, everybody!!!";
var shout = greeting.toUpperCase(); //where did toUpperCase come from?

As you can see from this brief snippet, your greeting variable, which stores a primitive value in the form of text, seems to have access to the toUpperCase method. How is this even possible? Where did that method come from? Why am I here? Answers to confusing existential questions like this will make up the bulk of what you see in this page. Also, I apologize for writing that previous sentence in passive voice. Happen again it won't.


OMG! A JavaScript Book Written by Kirupa?!!

To kick your JavaScript skills into outer space, everything you see here and more (with all its casual clarity!) is available in both paperback and digital editions.


Strings Aren't the Only Problem

Because of how cute they are, it's easy to pick on strings as the main perpetrator of this primitive/Object confusion. As it turns out, many of the built-in primitive types are involved in this racket as well. Below is a table of the built-in Object types with the guilty parties that also exist as primitives highlighted:

Type What it does
Array helps store, retrieve, and manipulate a collection of data
Boolean acts as a wrapper around the boolean primitive; still very much in love with true and false
Date allows you to more easily represent and work with dates
Function allows you to invoke some code among other esoteric things
Math the nerdy one in the group that helps you better work with numbers
Number acts as a wrapper around the number primitive
RegExp provides a lot of functionality for matching patterns in text
String acts as a wrapper around the string primitive

Whenever you are working with boolean, number, or string primitives, you have access to properties their Object equivalent exposes. In the following sections, you'll see what exactly is going on.

Let's Pick on Strings Anyway

Just as you were taught by your parents growing up, you typically use a string in the literal form:

var primitiveText = "Homer Simpson";

As you saw in the table earlier, strings also have the ability to be used as objects. There are several ways to create a new object, but the most common way to create an object for a built-in type like our string is to use the new keyword followed by the word String:

var name = new String("Homer Simpson");

The String in this case isn't just any normal word. It represents what is known as a constructor function whose sole purpose is to be used for creating objects. Just like there are several ways to create objects, there are several ways to create String objects as well. The way I see it, knowing about one way that you really shouldn't be creating them with is enough.

Anyway, the main difference between the primitive and object forms of a string is the sheer amount of additional baggage the object form carries with it. Let's bring our silly visualizations back. Your primitiveText variable and its baggage looks as follows:

what baggage?

 There really isn't much there. Now, don't let the next part scare you, but if we had to visualize our String object called name, here is what that would look like:

string overload

You have your name variable containing a pointer to the text, Homer Simpson. You also have all of the various properties and methods that go with the String object - things you may have used like indexOf, toUpperCase, and so on. You'll get a massive overview of what exactly this diagram represents in a future tutorial, so don't worry yourself too much about what you see here. Just know that the object form of any of the primitives carries with it a lot of functionality.

Why This Matters

Let's back to our earlier point of confusion. Our string is a primitive. How can a primitive type allow you to access properties on it? The answer has to do with JavaScript being really weird. Let's say you have the following string:

var game = "Dragon Age: Origins";

The game variable is very clearly a string primitive that is assigned to some literal text. If I want to access the length of this text, I would do something as follows:

var game = "Dragon Age: Origins";

As part of evaluating game.length, JavaScript will convert your primitive string into an object. For a brief moment, your lowly primitive will become a beautiful object in order to figure out what the length actually is. The thing to keep in mind is that all of this is temporary. Because this temporary object isn't grounded or tied to anything after it serves its purpose, it goes away and you are left with the result of the length evaluation (a number) and the game variable (still a string primitive).

This transformation only happens for primitives. If you ever explicitly create a String object, then what you create is permanently kept as an object. Let's say you have the following:

var gameObject = new String("Dragon Age:Origins");

In this case, our gameObject variable very clearly points to something whose type is Object. This variable will continue to point to an Object type unless you modify the string or do something else that causes the reference to be changed. The primitive morphing into an object and then morphing back into a primitive is something unique to primitives. Your objects don't partake in such tomfoolery.

You can easily verify everything I've said by examining the type of your data. That is done by using the typeof keyword. Here is an example of me using it to confirm everything I've just told you about:

var game = "Dragon Age: Origins";
alert("Length is: " + game.length);

var gameObject = new String("Dragon Age:Origins");

typeof game //string
typeof game.length //number
typeof gameObject //Object

Now, aren't you glad you learned all this?


Hopefully this brief explanation helps you to reconcile why your primitives behave like objects when they need to. At this point, you might have a different question around why anybody would have designed a language that does something this bizarre. After all, if a primitive turns into an object when it needs to do something useful, why not just stay an object always? The answer has to do with memory consumption.

As you saw from my discussion on how much more baggage the object form of a primitive carries when compared to just a primitive, all of those pointers to additional functionality cost resources. The solution in JavaScript is a compromise. All literal values like text, numbers, and booleans are kept as primitives if they are declared and/or used as such. Only when they need to are they converted to their respective Object forms. To ensure your app continues to keep a low memory footprint, these converted objects are quickly discarded (aka garbage collected) once they've served their purpose.

If you have a question about this or any other topic, the easiest thing is to drop by our forums where a bunch of the friendliest people you'll ever run into will be happy to help you out!


Get cool tips, tricks, selfies, and more...personally hand-delivered to your inbox!

( View past issues for an idea of what you've been missing out on all this time! )



Serving you freshly baked content since 1998!

Killer hosting by (mt) mediatemple

Facebook Twitter Youtube Pinterest Instagram Github
new books - yay!!!