typeof JavaScript tweaked

Most of the programming critters pawing at JavaScript would have used the typeof operator that returns a string indicating the type of the unevaluated operand.

But the well know confusing with typeof, is the string it returns!

  • typeof [] => "object"
  • typeof {} => "object"
  • typeof null => "object"

The below is a simple, but very effective tweak for the typeof operator

function typeOf (obj) {
    var _types = {
        'undefined': 'undefined',
        '[object Number]'   : 'Number',
        '[object Boolean]'  : 'Boolean',
        '[object String]'   : 'String',
        '[object Function]' : 'Function',
        '[object RegExp]'   : 'RegExp',
        '[object Array]'    : 'Array',
        '[object Date]'     : 'Date',
        '[object Error]'    : 'Error',
        '[object Object]'   : 'Object',
        '[object Boolean]'  : 'Boolean'
    };
    Object.freeze(_types);  // To avoid further manipulation.
    return _types[Object.prototype.toString.call(obj)];
}

Let's do a simple test!

>>> console.log([ {}, [], new Date(), new RegExp(),1, true, "hemanth.hm", undefined].map(typeOf))
["Object", "Array", "Date", "RegExp", "Number", "Boolean", "String", undefined]

Thus said and done, indeed there are many other ways of doing the same, do let me know your way!

Edit 0
Inspired by the suggestion given be Altreus below, I felt a isa() would be very useful in the Object prototype!

So here is the one liner for isa() implementation

Object.prototype.isa = function () { return  Object.prototype.toString.call(this).match(/\[object (.+)\]/)[1]; }

Now we have isa() for every object..... We can have more fun?!

If one feels using isa() is more easier, then there is a bit of change in the invocation. The invocation must be something like ({}).isa(), ([]).isa(), (new Date()).isa(), (new RegExp()).isa(), (1).isa(), (true).isa(), ("hemanth.hm").isa() , (undefined).isa() so on!

Edit 1
As per Jake Verbaten suggestion, instead of adding enumerable property for Object.prototype, it's better to use Object.defineProperty() as :

Object.defineProperty(Object.prototype, "isa", {
  configurable: true,
  value: function () {return  Object.prototype.toString.call(this).match(/\[object (.+)\]/)[1];}
});
Share this