Hemanth's Scribes

javascript

typeof JavaScript tweaked

Author Photo

Hemanth HM

Thumbnail

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 known confusion 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 by Altreus below, I felt an 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 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’s suggestion, instead of adding enumerable property for Object.prototype, it’s better to use Object.defineProperty():

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

About Hemanth HM

Hemanth HM is a Sr. Machine Learning Manager at PayPal, Google Developer Expert, TC39 delegate, FOSS advocate, and community leader with a passion for programming, AI, and open-source contributions.