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
Hooray!!
I'm not sure how
correctthis approach but it works and it's easy to remember.
No comments:
Post a Comment