Because of the need constantly arising on detecting data types, and I have written the following function that so far has served well, so I would like to share the code with you. However I'm beginning to think that this maybe isn't an efficient way for type detection. How could I enhance this function? Or am I making a mistake, and shouldn't even do this?
Based on cade's answer I reviewed and edited the code:
function detectType(data) {
// analyze data to distinguish object types from primitive types
var dataType = typeof data;
var toClass = {}.toString; // this is used to detect object types
var isPrimitive;
var isFalsy = false;
switch(dataType) {
case 'string':
isFalsy = !data;
if(isFalsy) {
dataType = 'empty string'; // Only if you want to distingush empty strings
}
isPrimitive = true;
break;
case 'number':
isFalsy = !data;
if(isFalsy) {
if(isNaN(data))
dataType = 'NaN'; // it is strange that JavaScript considers NaN a number
else {
dataType = '0'; // only needed if you want to distinguish zeros
if(1/data < 1/0)
dataType = '-0';
}
} else if(!isFinite(data)) { // Although infinity is considered a number you might want to distinguish it
dataType = 'infinity';
if(data < Infinity)
dataType = '-infinity';
}
isPrimitive = true;
break;
case 'boolean':
isFalsy = !data;
isPrimitive = true;
break;
case 'object':
isFalsy = !data;
dataType = toClass.call(data).slice(8, -1).toLowerCase();
switch(dataType) {
case 'string':
dataType = 'object string';
break;
case 'number':
dataType = 'object number';
break;
case 'boolean':
dataType = 'object boolean';
break;
}
isPrimitive = false;
break;
case 'function':
isFalsy = !data;
isPrimitive = false;
break;
case 'undefined':
isFalsy = !data;
isPrimitive = false;
break;
}
return [dataType, isPrimitive ,isFalsy];
}
I tried a few things in console and got these results:
detectType(-0)
["-0", true, true]
detectType(9)
["number", true, false]
detectType(new Number(3))
["object number", false, false]
detectType('')
["empty string", true, true]
detectType('foo')
["string", true, false]
detectType(new String('bar'))
["object string", false, false]
detectType(true)
["boolean", true, false]
detectType(new Boolean(false))
["object boolean", false, false]
detectType(document.body)
["htmlbodyelement", false, false]
detectType(-0)
["-0", true, true]
detectType(-Infinity)
["-infinity", true, false]
detectType(/a-zA-Z/)
["regexp", false, false]
Now It can even detect html elements too, it is possible to check for -0, +0 and -Infinity, +Infinity, although these are considered numbers, one might find it useful to distinguish too large or too small numbers such is infinity or -0.