Type Checking in JavaScript

At first, type checking may seem like a straightforward concept. A value can either be an object, a function, an array, a number, a string, a boolean, null, or undefined. JavaScript has the typeof operator which returns a string indicating the type of the operand.

typeof 5 === 'number'
// true

Easy as pie, right? Unfortunately, typeof is not as reliable as you might think.

What does the following equal?

typeof NaN

If you said number, you’d be correct. NaN does in fact behave like a number.

What about this one?

NaN === NaN

This is false. Why? Because NaN represents any computational value that does not make mathematical sense. For instance, Math.log(-5) gives NaN and so does 'hello' * 5. However, Math.log(-5) definitely doesn’t equal 'hello' * 5. Hence, NaN !== NaN. NaN results in false when compared to anything.

We can test to see if something is or is not NaN by using the isNaN function.

// true

// true


What do we get here?

typeof null

We get object. This is a mistake that has been around since the beginning of JavaScript. I recommend reading Dr. Axel Rauschmayer’s post for more information on the history of the blunder. Fixes have been proposed and rejected so we are most likely stuck with it.

How about the following?

typeof [1,2,3]

Again, the answer is confusingly object. How do we test if something is actually an array then? The Array constructor function has the isArray method that conveniently returns true if an object is an array, and false if it is not.



Here is a typeof summary.

 type  typeof
 object  object
 function function
 array object
 number number
string string
boolean boolean
null object
undefined undefined

Our journey does not end here. Evaluate the following:

typeof new Number(5)

The answer yet again is object. It is true when they say that everything is really an object in JavaScript. That is, with one exception: primitive values. Primitives values are just that – values. They are not objects so they have no properties or methods. In JavaScript, there are five primitive data types: strings, numbers, booleans, null and undefined.

These are examples of primitive values:


With the exception of null and undefined, primitive values also have object equivalents which wrap around the primitive values. new Number(5) is an example of this and thus is why typeof new Number(5) === 'object' is true.

All objects have the valueOf method which returns the primitive value of the specified object.

var myNum = new Number(5);

myNum.valueOf() === 5
// true

typeof myNum.valueOf() === 'number'


Does the following work?

var myStr = 'hello there',
    myArr = myStr.split(' ');

// ['hello','there']

If myStr is a primitive value with no properties or methods, then why does the split method obviously work here? In cases like this, the primitive is temporarily converted to its object equivalent so that it can utilize its object version’s properties. However, after the method call, myStr is still a primitive value of type string. You will not be able to add your own properties to it (but it won’t throw when you try either).

var myStr = 'hello there';

myStr.testing = 'testing';

// undefined

var myStr2 = new String('hello again');

myStr2.testing = 'testing';

// testing


What about the following?

typeof new Function('a','b','return a+b')

This is indeed function. But, if everything in JS is an object, then what does it even mean to be of type function? In the example above, we are using the new keyword on the Function constructor function to create a new object. This newly generated object is a function object. Function objects are special objects that inherit from the Function constructor function’s prototype.

So, if typeof new String('hello') === 'object' and typeof {} === 'object' then how can we really differentiate between the two? All objects have a toString method which returns a string that represents the object.

// [object Object]

It is important to note that arrays and strings have their own toString methods.

// 1,2,3

// 'hello'

To get around this, we can use the call method on the toString method found in the Object constructor function’s prototype. That’s a mouthful but here is what it looks like:

// [object Array]

// [object String]

Codewars offers excellent, free JavaScript coding challenges. Typer.js is a Codewars exercise that requires you to create a basic type-checker “framework/api” for JavaScript. I suggest you head on over there, create an account if you aren’t a member, and try your hand at the problem. My solution is below.

var typer = (function() {

    var _toString = Object.prototype.toString;

    function toStringCheck(val,test) {
      return _toString.call(val) === _toString.call(test);

    function isNumber(val) {
      return !isNaN(val) && toStringCheck(val,new Number());

    function isString(val) {
      return toStringCheck(val,new String());

    function isArray(val) {
      return Array.isArray(val);

    function isFunction(val) {
      return typeof val === 'function';

    function isDate(val) {
      return toStringCheck(val,new Date());

    function isRegExp(val) {
      return toStringCheck(val,new RegExp());

    function isBoolean(val) {
      return toStringCheck(val,new Boolean());

    function isError(val) {
      return toStringCheck(val,new Error());

    function isNull(val) {
      return val === null;

    function isUndefined(val) {
      return val === undefined;

    return {
      isNumber: isNumber,
      isString: isString,
      isArray: isArray,
      isFunction: isFunction,
      isDate: isDate,
      isRegExp: isRegExp,
      isBoolean: isBoolean,
      isError: isError,
      isNull: isNull,
      isUndefined: isUndefined


It should be noted that toStringCheck could have also been used in isArray, isFunction, isNull, and isUndefined but I went with a simpler solution when there was one.

Leave a comment and follow me on twitter: @QuintonAiken