The typeof
operator doesn\'t really help us to find the real type of an object.
I\'ve already seen the following code :
Object.prototyp
the Object.prototype.toString
is a good way, but its performance is the worst.
http://jsperf.com/check-js-type
Use typeof
to solve some basic problem(String, Number, Boolean...) and use Object.prototype.toString
to solve something complex(like Array, Date, RegExp).
and this is my solution:
var type = (function(global) {
var cache = {};
return function(obj) {
var key;
return obj === null ? 'null' // null
: obj === global ? 'global' // window in browser or global in nodejs
: (key = typeof obj) !== 'object' ? key // basic: string, boolean, number, undefined, function
: obj.nodeType ? 'object' // DOM element
: cache[key = ({}).toString.call(obj)] // cached. date, regexp, error, object, array, math
|| (cache[key] = key.slice(8, -1).toLowerCase()); // get XXXX from [object XXXX], and cache it
};
}(this));
use as:
type(function(){}); // -> "function"
type([1, 2, 3]); // -> "array"
type(new Date()); // -> "date"
type({}); // -> "object"
I'd argue that most of the solutions shown here suffer from being over-engineerd. Probably the most simple way to check if a value is of type [object Object]
is to check against the .constructor
property of it:
function isObject (a) { return a != null && a.constructor === Object; }
or even shorter with arrow-functions:
const isObject = a => a != null && a.constructor === Object;
The a != null
part is necessary because one might pass in null
or undefined
and you cannot extract a constructor property from either of these.
It works with any object created via:
Object
constructor{}
Another neat feature of it, is it's ability to give correct reports for custom classes which make use of Symbol.toStringTag
. For example:
class MimicObject {
get [Symbol.toStringTag]() {
return 'Object';
}
}
The problem here is that when calling Object.prototype.toString
on an instance of it, the false report [object Object]
will be returned:
let fakeObj = new MimicObject();
Object.prototype.toString.call(fakeObj); // -> [object Object]
But checking against the constructor gives a correct result:
let fakeObj = new MimicObject();
fakeObj.constructor === Object; // -> false
The JavaScript specification gives exactly one proper way to determine the class of an object:
Object.prototype.toString.call(t);
http://bonsaiden.github.com/JavaScript-Garden/#types
Accepted answer is correct, but I like to define this little utility in most projects I build.
var types = {
'get': function(prop) {
return Object.prototype.toString.call(prop);
},
'null': '[object Null]',
'object': '[object Object]',
'array': '[object Array]',
'string': '[object String]',
'boolean': '[object Boolean]',
'number': '[object Number]',
'date': '[object Date]',
}
Used like this:
if(types.get(prop) == types.number) {
}
If you're using angular you can even have it cleanly injected:
angular.constant('types', types);
var o = ...
var proto = Object.getPrototypeOf(o);
proto === SomeThing;
Keep a handle on the prototype you expect the object to have, then compare against it.
for example
var o = "someString";
var proto = Object.getPrototypeOf(o);
proto === String.prototype; // true
The best solution is toString
(as stated above):
function getRealObjectType(obj: {}): string {
return Object.prototype.toString.call(obj).match(/\[\w+ (\w+)\]/)[1].toLowerCase();
}
FAIR WARNING: toString
considers NaN
a number
so you must manually safeguard later with Number.isNaN(value)
.
The other solution suggested, using Object.getPrototypeOf
fails with null
and undefined