The typeof operator in JavaScript evaluates and returns a string with the data type of an operand. For example, to find the type of 123 , we would write -

typeof 123

This will return a string with the type of 123 , which, in this case, will be "number". In addition to "number", the typeof operator can return one of 6 potential results -

typeof 123 // "number" typeof "abc" // "string" typeof true // "boolean" typeof {a: 1} // "object" typeof function foo() {} // "function" typeof undefined // "undefined" typeof Symbol('foo') // "symbol"

In the above examples, it's pretty straightforward what the type of the operands will be. However, there are a few cases where it is unclear or misunderstood what the type of the operand should be.

What's the typeof typeof 123 ?

typeof typeof 123 // "string"

What is the type of a typeof expression? Well, the typeof operator always returns a string with the type of the operand passed to it. If the resultant type of the expression is, for example, a number, what will be returned is "number" . This means that, regardless of resultant type, the type of a typeof [any operand] , will always be a string.

What's the typeof NaN ?

typeof NaN // "number"

The type of NaN , which stands for Not a Number is, surprisingly, a number. The reason for this is, in computing, NaN is actually technically a numeric data type. However, it is a numeric data type whose value cannot be represented using actual numbers. So, the name "Not a Number", doesn't mean that the value is not numeric. It instead means that the value cannot be expressed with numbers.

This also explains why not all NaN values are equal. For example -

const NaN1 = 2 * "abc"; const NaN2 = 2 * "abc"; NaN1 === NaN2 // false

Those two NaN values are not equal because they are not necessarily the same unrepresentable number.

What's the typeof [1,2,3] ?

typeof [1,2,3] // "object"

The typeof an array is an object. In JavaScript, arrays are technically objects; just with special behaviours and abilities. For example, arrays have a Array.prototype.length property, which will return the number of elements in the array. Arrays also have special methods, e.g. Array.prototype.push() or Array.prototype.unshift() (See JavaScript Array Methods - Mutator Methods).

To differentiate an Array object from an Object object, we can use the Array.isArray() method.

Array.isArray( [1,2,3] ) // true Array.isArray( { a: 1 } ) // false

What's the typeof null ?

typeof null // "object"

The null value is technically a primitive, the way "object" or "number" are primitives. This would typically mean that the type of null should also be "null". However, this is not the case because of a peculiarity with the way JavaScript was first defined.

In the first implementation of JavaScript, values were represented in two parts - a type tag and the actual value. There were 5 type tags that could be used, and the tag for referencing an object was 0 . The null value, however, was represented as the NULL pointer, which was 0x00 for most platforms. As a result of this similarity, null has the 0 type tag, which corresponds to an object.

What's the typeof class Foo {} ?

typeof class Foo {} // "function"

Finally, we have Classes. Classes were introduced in ES2015 (ES6) as a better syntax for prototype-based inheritance. Before Classes, to make an inheritable object, we would have to use a function.

function Dog() { } Dog.prototype.bark = function() { alert("woof!"); } const snoopy = new Dog(); snoopy.bark() // alert("woof!")

With Classes, we can create the same object this way -

class Dog { bark() { alert("woof!"); } } const snoopy = new Dog(); snoopy.bark() // alert("woof!")