One of the notorious pitfalls of javascript is that it’s not easy to determine types. The typeof operator, which is the native way of retrieving the type of an element, commits the following atrocities:
object
,array
,regex
,date
andnull
are all consideredobject
nan
,infinity
,integer
andfloat
are all considerednumber
I am exaggerating somewhat – the only real atrocity here is to consider null
as an object.
As for the rest of the simplifications, they are justified by the fact that 1) everything’s an object in javascript; and 2) there’s no different types of numbers in javascript, in contrast to other languages where’s genuine differences between different types of numbers.
However, typeof isn’t all that bad. It appropriately detects the following types: boolean
, string
, undefined
and function
.
Justifications aside, you really want to know the type of whatever your functions will receive. The good news is that this can be solved with a type function that is 16 lines long and will work anywhere. It is based on Douglas Crockford’s type function.
function type (value, objectType) { var type = typeof value; if (type !== 'object' && type !== 'number') return type; if (value instanceof Array) return 'array'; if (type === 'number') { if (isNaN (value)) return 'nan'; else if (! isFinite (value)) return 'infinity'; else if (value % 1 === 0) return 'integer'; else return 'float'; } type = Object.prototype.toString.call (value).replace ('[object ', '').replace (']', '').toLowerCase (); if (type === 'array' || type === 'date' || type === 'null') return type; if (type === 'regexp') return 'regex'; if (objectType) return type; return 'object'; }
type
takes a single argument (of any type, naturally) and returns a string which can be any of: nan
, infinity
, integer
, float
, array
, object
, regex
, date
, null,
function, boolean,
string
, and undefined
.
If you pass a truthy second argument to type
, and input
turns out to be an object, type
will return the lowercased name of the class of the object (which, for example, can be object
for object literals, arguments
for arguments
pseudo-arrays, and other values for user-created classes).
Here’s a detailed explanation of how the function works.
I use this function in every library I’ve written and every project where I work. I encourage you to try it out.