Also available at

Also available at my website and on Twitter @toshafanasiev

Thursday, 28 January 2010

Making instanceof work for you

When writing generic JavaScript code, you need to be able to handle a wide range of input values and often take different actions based on their type. To detect a value's type, the instanceof operator is often employed, but to varying degrees of success due to a subtlety in its behaviour.

The instanceof operator returns true if the operand to its left is an instance of the object type to it's right ( go here for more detail ), but the results can sometimes be surprising:

// "hi there" is a String, right?
( "hi there" instanceof String ) == false
( new String( "hi there" ) instanceof String ) == true
// sometimes?

The key here is the phrase instance of object type; literal values such as "hi there" and 3.141 are not objects, they are primitive values, or primitives for short, and as such are not instances of any object type, and so do not meet the criteria for instanceof .

The confusion arises from the fact that literals apparently support object instance methods:

// these both work
window.alert( 3.141 .toString() ); // note the gap
window.alert( "hi there".split( /\s+/ )[0] );

JavaScript, like the Java Runtime and the .NET CLR ( and many other VMs ), does something behind the scenes to make calls like the two above legal: it wraps a primitive value in a true Object and applies the instance method call to that object, a process known as boxing.

The fact that JavaScript boxes primitives for method calls but not for instanceof evaluation is a design decision, rather than an error; and armed with this knowledge, we can make instanceof work for us. Here is a little utility function I wrote ( I borrowed the name from a CLR IL opcode ) that I have found very useful:
function isinst( value, type ) {
// box before testing
return new Object( value ) instanceof type;

And now:

isinst( 7, Number ) == true
isinst( "hi there", String ) == true
isinst( new String( "hi there" ), String ) == true


I'm not sure how correct this approach but it works and it's easy to remember.

No comments:

Post a Comment