Javascript Type Gotchas
May 1st, 2010typeof null // -> object null instanceof null // -> TypeError: Can't use instanceof on a non-object. true instanceof Boolean // -> false true == new Boolean(true) // -> true true === new Boolean(true) // -> false
Needless to say, this is very annoying if you’re trying to be be careful with your types and just goes to show that not everything is an object in Javascript. Come back soon for my attempt at a solution.
May 28th, 2010 at 7:13 pm
You had me going for a few minutes… and now I understand the difference between the typeof and instanceof operators. :)
In javascript, a “type” is different from a “class” (the object it is an instance of). So “typeof” will only return whether it is a number, boolean, string, or object. The “instanceof” operator is meant to be used on objects, to figure out what kind of object it is. So…
typeof null
// returns “object” because this variable is technically a null object
null instanceof null
// well, “null” isn’t an object type (i.e. an type you defined with a constructor)
// I think what we meant was:
null instanceof Object
// returns false, because null is not an instance -> it is the lack of an instance
true instanceof Boolean
// returns false, because true is not an instance of an Object, it is a primitive type
// That explains the last two examples too.
Thanks for the lesson!
May 29th, 2010 at 12:04 am
Yep, you’ve basically got it Collin.
However, there are no such things as classes in Javascript. Rather,
instanceoftells you whether the left-hand side object is in the right-hand side object’s prototype chain. This is why(new String) instanceof String == trueand(new String) instanceof Object == true: bothStringandObjectare innew String‘s prototype chain. Granted, the same would be true ifStringwere a subclass ofObjectin a class-based inheritance system, but remember that Javascript uses a prototype-based inheritance system and there can and often are subtle differences.When you use the
newoperator on a function (sayString) in Javascript, it is essentially the same asString.call({}). That is, theStringfunction is being called with an empty object as itsthisvalue. Thisthis(excuse the pun) functionality means that you can have something akin to mixins.String.call(Number.call({}))should give you an object with both string and number methods. I haven’t tested this, so I can’t promise it works.So, returning to your conclusions from the examples, your explanations are spot on except that
nullreally isn’t an object. I believe it’s a mistake in Javascript to return"object"fromtypeof null. Instead, I believe it is a primitive, not an object, and should returnnull.The solution I was hinting at, and still need to blog about, is typed.js, a better, ‘replacement’ type system for Javascript. It will give you consistent, rational type information. For instance,
nullis always aNullTypein my type system.