Javascript Type Gotchas

May 1st, 2010
typeof 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.

2 responses

  1. Collin Donahue-Oponski comments:

    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!

  2. Peter comments:

    Yep, you’ve basically got it Collin.

    However, there are no such things as classes in Javascript. Rather, instanceof tells you whether the left-hand side object is in the right-hand side object’s prototype chain. This is why (new String) instanceof String == true and (new String) instanceof Object == true: both String and Object are in new String‘s prototype chain. Granted, the same would be true if String were a subclass of Object in 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 new operator on a function (say String) in Javascript, it is essentially the same as String.call({}). That is, the String function is being called with an empty object as its this value. This this (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 null really isn’t an object. I believe it’s a mistake in Javascript to return "object" from typeof null. Instead, I believe it is a primitive, not an object, and should return null.

    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, null is always a NullType in my type system.

Leave a comment