Relying on the instanceof
operator is not good enough for some cases.
A known problem is that it wonk doesn't work on cross-frame environments.
The typeof
operator is not so useful, and there are some implementation bugs, for example like in Chrome or Firefox 2.x, where RegExp
objects are detected as "function"
, because they have made callable (e.g. /foo/(str);
).
The constructor
property can be tampered, and you should never put much trust on it.
And finally, the Function.prototype.toString
method is implementation dependent, meaning that the implementation may not include even the function name in the string representation of the function...
Some days ago I was building a simple but robust type detection function, it uses typeof
for primitive values, and relies on the [[Class]]
internal property for objects.
All objects have this property, implementations use it internally to detect the kind of the object, it is completely immutable, and is only accessible through the Object.prototype.toString
method:
Usage:
//...
if (typeString(obj) == 'array') {
//..
}
Implementation:
function typeString(o) {
if (typeof o != 'object')
return typeof o;
if (o === null)
return "null";
//object, array, function, date, regexp, string, number, boolean, error
var internalClass = Object.prototype.toString.call(o)
.match(/\[object\s(\w+)\]/)[1];
return internalClass.toLowerCase();
}
The second variant of this function is more strict, because it returns only built-in object types described in the ECMAScript specification.
Possible output values:
Primitives:
"number"
"string"
"boolean"
"undefined"
"null"
"object"
Built-in object types (through [[Class]]
)
"function"
"array"
"date"
"regexp"
"error"