Just the weekly tutorials.

Learning JavaScript Primitive Coercion

Often when we learn a new language we want to start using it right away. It's easy to jump into writing a computer program using vars, functions, etc. It is equally easy to figure out how the dot(.) operator works to retrieve properties and methods of an object.

When that happens we start believing that we know the basics. But we are fooling ourselves. What actually happens is that we learn the advanced techniques and think of them as the basics. In reality, not fully (or at all) realizing how or why they work. We just know that they do.

Sometimes a complex tool appears to be simple, because of its versatility. That still doesn't mean that just because it's easy to use it is basic. I am only saying this that making the mistake of seeing a complex thing as something basic, we only fool ourselves and make our own journey to becoming a JavaScript programmer more difficult and less enjoyable. We are supposed to "love what we do" and not spend hours being frustrated with it.

The problem is simple to understand. Once we learn vars, functions, arrays and objects, it seems that at this point we have all the tools we need and we move on trying to figure out how to write our program and apply a bunch of hacks along the way.

And it's not that we skip all the significant details when we rush into writing code without learning the language. It's that we avoid learning the very basics. For example, not many people spend any time learning JavaScript primitives, let alone primitive coercion. And these are the smallest building blocks of any computer program written in JavaScript, which also become very important when writing jQuery code.

Not understanding primitive coercion is like trying to drive a car not knowing that it needs a gas refill every once in a while. Eventually, your understanding of your own program will come to a halt, once you start wondering why "the code didn't work, even though it looks just right."

How many times did you have an experience when your code didn't work even though you were convinced that it should? Unawareness of primitive coercion causes this type of a situation. I've done my research. And I can totally see it. Below I'll explain what it is and how to get better at not just writing, but understanding your JavaScript program. Why sometimes it works. Why most of the time it doesn't.

A lot of bugs can be avoided by understanding the principles of coercion, and lots of time can be saved. The only reason I bring it up is that JavaScript programming can be fun... but only if you understand the tools you're dealing with (the language itself.) So let's get to it!

First, what are primitives?

Primitives

Let's take a look at the following statements:

var x = 1; var y = "One";

The x and y refers to a variable name. But what is the value? The value is the primitive.

But there is one little thing. Even though a primitive is a value, a primitive cannot be an object. If it were, it wouldn't be a primitive:

var z = new Object();

Primitives are not objects. They are values. So z refers to a value that is not a primitive in this case.

Primitive Coercion

Let's examine the definition of the word coerce:

co·erce

In computer programming:

I think we're interested in definition #3 :-)

Primitives are part of the language design. They are also serving the internal memory efficiency mechanisms. And primitive coercion is both, a language design and a feature we can use as programmers. We just said how primitives are not objects. Knowing this, we can understand primitive coercion which is what happens when a primitive becomes an object.

But when does that happen? It happens automatically. And most of the time we're not even aware of this. Let's take a look at several examples:

Primitives are values. Unlike objects they do not have properties.

In JavaScript there are 5 primitive types: null, boolean, string, number and undefined.

The number and string are the most common ones. You've seen them in the previous example. here they are again:

var x = 1; // 1 is the primitive of type number (not an object) var y = "One"; // "One" is the primitive of type string (not an object)

You can verify this by using typedef. Which will tell you the type of the primitive a value was assigned:

typedef(x); // returns "number" typedef(y); // returns "string"

The typedef function identifies objects too. It's not limited to primitives. But keep in mind primitives are not objects. You just have to memorize the 5 types of primitives.

An interesting thing happens when we start doing things to primitives. A digit can become an object of type Number. A text in a string can become an object of type String:

var x = "Hello"; // here the object does not exist yet. The value is only a primitive. alert(x.length); // outputs 5

This is coercion. By using the dot operator we turned a primitive "Hello" (which was not an object) into an object. As you can see, there is a lot going on within the dot, that is not at first obvious.

And thereafter, now that it is an object, we were able to access a property length of the object that was just created on the spot. The length property is a property that belongs to the object of type String. Numbers don't have that property.

We can do inline coercion by doing the following:

alert("Hello".length);

Here we create a primitive of type string and then convert it to an object of type String. Now that it is an object we get its length which stores the value 5. Which, incidentally is a primitive of type integer.

In JavaScript there is a global object method called valueOf(); We can use it on an object to "reverse engineer" the value back to its primitive type. And if it cannot be done (for example if it is in fact a custom object or an object whose value is not on the list of the 5 primitive types) then the value will refer to the object itself.

But that's not all. We have to use the typeof keyword together with valueOf() to find out whether it's actual value (or literal value) a primitive or not:

typeof ("Hello"); // string typeof (new String("Hello"); // object typeof (new String("Hello").valueOf()); // string (again)

As you can see there is a difference between a string primitive and String object.

typeof true; // boolean

We have successfully identified the boolean primitive type.

Let's try to add two strings and see if they are still coerced into a primitive:

alert(typeof "a" + "b"); // stringb

Interestingly, this will output "stringb". I believe this is because typeof "a" returns a string itself. And it is merged with "b". In order to find out what "a" + "b" really coerces to we need to use the parenthesis around the statement:

alert(typeof ("a" + "b")); // string

Now it is correct!

Primitives and literals

Primitives such as number 7 or 10 are also literals. What does it mean? It means nothing more than 1 is the literal representation of the number 1. And a string literal "Hello" (which is a primitive) is also the string literal. It is the literal representation of the text "Hello" as text. Neither literal 1 nor literal "Hello" are objects. They are the literal expressions of something.

Object literal

Because we now understand number and string literals we can grasp the idea of an object literal. What is that? Aren't objects stored in memory? Of course. But so are objects of type Number and String... that is, when they are indeed objects. But when they are not, they are literal representation of the value...or the primitives.

We only have 5 types of primitives in JavaScript. And none of them are objects. So what is this object literal that is not a primitive then? It is the literal expression of an object. The { } brackets and the colon were chosen to represent the object literal format:

var obj_lit = { a: 1 };

And an object literal containing more than one property:

var obj_lit = { a: 1, b: "Hello" }; alert(obj_lit.a); // 1 alert(obj_lit.b); // Hello

JSON vs object literal

But there is another format for representing objects. This is the JSON string format. Why was it created? Object literals represented by { } are simple JavaScript statements. Over a period of time they became so useful that other languages decided to inherit it (Sometimes with the help of additional libraries.)

Object literals contain data for entire objects, not just a primitive type which is useful only to the language being used. But many favorite languages use objects. And on the Internet it is common for an application to be written in several different languages (JavaScript, ActionScript 3.0, PHP, Java...etc.)

When one language needs to share an entire object over the network, how do we transfer it from one language to another? Well, most of the data that is transferred over the network comes as text (characters) and JSON format was invented as a string format, to fulfill this purpose.

JSON is the same as the regular object literal, except there are a few rules:

var json_obj = '{ "a": 1, "b": "Hello" }';

This is the properly formed JSON object. Take away the single quotes from a and b values, and it will no longer be a correct JSON format. That's important. Keep those quotes up. It probably doesn't matter which quotes you use: single or double. But since JSON object is a only string itself some quote juggling is expected.

Now you can pass this JSON to an HTTP Ajax call, and off it goes over the network to another app or platform.

When the JSON string is received in an application, it is converted back into the custom object in that language. If JavaScript received the JSON object from a Java or PHP server, it will convert it into an object literal (custom object) format again.

Just the weekly tutorials.