Alternative way of determining type in JavaScript

July 22, 2020

javascript

For many of us, when we first learned JavaScript, the first obvious way we came across for determining type was of course by using the typeof operator, which works fine for most basic use cases.

let value;

typeof 30; // number
typeof true; // boolean
typeof 'hello world'; // string
typeof function () {}; // function
// undefined
typeof undefined; // undefined
typeof value; // undefined
typeof notSet; // undefined

But as you progress with learning the language, you come across some murky waters like dealing with the null primitive as discussed in this Stackoverflow post and dealing with the many types of objects floating around (native or otherwise).

typeof null; // object
typeof { a: 1 }; // object
typeof /s/; // object
typeof new RegExp('s'); // object
typeof new Date(); // object

For a long time, I just went along with just using typeof operator, as I would assume most developers do initially, using a few ideas and hacks from all over the internet whenever I needed something different. For me especially, it was either from Stackoverflow or Dr. Axel Rauschmayer’s wonderful book Speaking JavaScript.

So, what to do? Fortunately, as I was looking through the code of the vue.js JavaScript framework, I came across a piece of code (which I made a few modifications to) that I thought I could use for a project I was working on and I have been using it in pretty much every JavaScript project since.

const is = function (value) {
    const toString = Object.prototype.toString;

    // OR return ({}).toString.call(value).slice(8, -1).toLowerCase();
    return toString.call(value).slice(8, -1).toLowerCase();
};

That is all.

We can compare the results from the function above to those produced by the typeof operator and see how they match up.

is(30); // number
typeof 30; // number
is(true); // boolean
typeof true; // boolean
is('hello world'); // string
typeof 'hello world'; // string
is(function () {}); // function
typeof function () {}; // function

// undefined
is(undefined); // undefined
typeof undefined; // undefined
is(value); // undefined
typeof value; // undefined
// is(notSet); // Throws ReferenceError
typeof notSet; // undefined

// murky waters
is(null); // null
typeof null; // object
is({ a: 1 }); // object
typeof { a: 1 }; // object
is(/s/); // regexp
typeof /s/; // object
is(new RegExp('s')); // regexp
typeof new RegExp('s'); // object
is(new Date()); // date
typeof new Date(); // object

As you can see, the function handles null quite well, plus Date and Regex objects. You can also test it with some recent additions to JavaScript language like Symbol, Bigint, Map, Set, etc. and the results will be just as you expect them.

If you are inclined towards tighter type control seen in languages like C++, Java, C#, and others, you should consider looking into typescript.

Thank you for reading and God bless.