typeof vs instanceof

Both of these operators are used to check if an object is of  specific type. So, which one should you use? The answer is: it depends…I guess that none of them is perfect. typeof will always return a string which identifies the “current type” (and this info is really useless most of the time). On the other hand, instanceof will always require two operands: and object and a “type”. It will only return true if the object is of that type. Here are a couple of examples:

var info = typeof { name: "luis" }; //"object"
var isObject = { name: "luis"} instanceof Object; //true

As you can see, one of the downsides of using typeof is that you end up comparing strings. But there are far worse things which can happen when you use this operator:

var info = typeof null; //"object"

ooppss…Yes, that’s right: typeof null returns object…not good, right? Nevertheless, there’s a simple solution for this kind of glitch: you can use the logical && operator and add an extra condition that tests for null (notice that I’m thinking in scenarios where you’re using an if to check for the current type of an object).

Unfortunately, there are other gotchas which might get you. Here’s another interesting snippet:

var info1 = typeof 10; //number
var info2 = typeof new Number(10); //object

If you’ve been doing JS for some time, this shouldn’t really surprise you, but the truth is that most people wouldn’t expect different results for the typeof in scenarios like the one I’ve shown. Yes, you can say that you’ll never use the Number type for creating a new number (I wouldn’t do that either), but what happens when you need to write a lib that will be used by other people?

I guess this means we can strike out typeof from our initial list of operators,right? That leaves us with the instanceof operator. When you start looking at it,everything looks good: you’re using types, so you shouldn’t get those nasty string errors (in the past, I’ve blown away simple typeof tests by missing a char on the string I was using on the comparison with the result returned from typeof). Here’s a quick example where instanceof works:

var info1 = [1,2,3] instanceof Array; //true
var info2 = new Array(1, 2, 3) instanceof Array; //true

the instanceof operator checks the prototype property to see if the passed constructor (second operand used with the instanceof operator) is the same as the one used for instantiating the first operand. btw, if you’re a JS developer for some time, you probably know that this won’t work when you use frames. And if you try that with numbers, you’re back to square one:

var info1 = 1 instanceof Number; //false
var info2 = new Number(1) instanceof Number; //true

(Just a small detour to remind you that numbers are primitive types and that means there’s no prototype property on them and that’s why instanceOf won’t really work with info1; on the other hand, info2 is an object and that’s why you’ll get the expected result when you use the instanceof operator).

The good news is that there was a guy that noticed that he could use the toString method of the Object prototype to get the correct description of the current object (I don’t know who introduced this technique first – for instance, I believe that JQuery has been using it since late 2008, though it uses it only in a limited scenarios and doesn’t slice the returned string). You’re back to strings again, but at least this works in all the previous scenarios. Here’s a quick example:

var info1 = 1;
var info2 = new Number(1);
var getClassName = function(type) {
    var prot = Object.prototype.toString;
    return prot.call(type).slice(8, -1);
alert(getClassName(info2)); //Number

As you can see, using the helper getClassName will always return the string “Number” (even in those cases where you’re using a “primitive” number). After running a quick search, I was able to get a good compilation of values that are returned from this method. As you can see from that list, this is probably one of your best options for those scenarios where you need to know the type of an object.

And that’s it for now. Stay tuned for more on JavaScript.


~ by Luis Abreu on September 19, 2009.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: