Alexander Dickson

JavaScript's typeof operator

JavaScript’s typeof operator is a curious thing. Many people says it lies, but in fact, it always does what it’s told.

typeof primitive

When using typeof on a primitive, we always get the response we generally want (with the exception being null, read on)…

typeof 1; // "number"
typeof ""; // "string"
typeof true; // "boolean"
typeof bla; // "undefined"
typeof undefined; // "undefined"

typeof some object

If you use typeof with an object, you get "object". That makes sense right? But what about these wonderful quirks…

typeof []; // "object"
typeof null; // "object"
typeof /regex/ // "object"
typeof new String(""); // "object"

An array returns "object" because an Array is just a special object ([] instanceof Object == true).

With regards to the null case, you may be thinking: WTF mate? Well, it’s because the specification states that typeof should return "object" for the null type. Some people say it’s because null is expected as the absence of an object, but I don’t know if that’s a valid justification. Crockford has been trying to get it to return "null" for a while, but it has the potential to break existing scripts (Crockford’s own JSON parser is even future-compatible).

A regular expression is an "object" because it’s an object, just like Date, etc. Super simple stuff, right?

It gets a little trickier when we check the typeof a String object. It returns "object", because our string is no longer a primitive. You can sometimes be bitten here, because for the most part, you can treat a string primitive and object as the same thing (the primitive will be boxed to an object when required).

For a rock solid method of not giving a shit if it’s a primitive or an object, we can detect the objects [[class]] by calling Object’s toString() method with any object as its context, and then extracting the value from the resulting string (I like to use slice(8, -1)).

({}).toString.call(someObj) == "[object String]";

You can always swap {} with Object.prototype, to save creating an object just to exploit its toString() method.

Other typeof quirks

When checking for a function, typeof returns "function" when the operand looks like a function. In older Safaris, however, the regex object could be called like a function (because it implemented [[call]]), so typeof /regex/ == "function". This has been fixed in newer Safaris. This also means that you can rely on typeof for functions, as anything that says it’s a function can be called as a function.

It’s not a tumour function!

You often see people write their code as if the typeof operator were not an operator, but a function…

if (typeof(str) == "string") {
    // ...
}

This is as stupid as writing num = 4 * (2). Please don’t do it. While we are here, I may as well mention that === is not necessary when comparing the response of typeof, which is always a string. When both operands are the same, == and === perform the same steps, so save the world by saving a character.

Go forth and use typeof where it makes sense

Hopefully now if you weren’t too sure about typeof, now you are. Once you understand it and its quirks, you should now know where you should use it and why you sometimes shouldn’t rely on it.


Want to discuss this post? Just mention me @alexdickson.