How to get a JavaScript object's class?
There's no exact counterpart to Java's getClass()
in JavaScript. Mostly that's due to JavaScript being a prototype-based language, as opposed to Java being a class-based one.
Depending on what you need getClass()
for, there are several options in JavaScript:
typeof
instanceof
obj.
constructor
func.
prototype
,proto
.isPrototypeOf
A few examples:
function Foo() {}
var foo = new Foo();
typeof Foo; // == "function"
typeof foo; // == "object"
foo instanceof Foo; // == true
foo.constructor.name; // == "Foo"
Foo.name // == "Foo"
Foo.prototype.isPrototypeOf(foo); // == true
Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21); // == 42
Note: if you are compiling your code with Uglify it will change non-global class names. To prevent this, Uglify has a --mangle
param that you can set to false is using gulp or grunt.
obj.constructor.name
is a reliable method in modern browsers. Function.name
was officially added to the standard in ES6, making this a standards-compliant means of getting the "class" of a JavaScript object as a string. If the object is instantiated with var obj = new MyClass()
, it will return "MyClass".
It will return "Number" for numbers, "Array" for arrays and "Function" for functions, etc. It generally behaves as expected. The only cases where it fails are if an object is created without a prototype, via Object.create( null )
, or the object was instantiated from an anonymously-defined (unnamed) function.
Also note that if you are minifying your code, it's not safe to compare against hard-coded type strings. For example instead of checking if obj.constructor.name == "MyType"
, instead check obj.constructor.name == MyType.name
. Or just compare the constructors themselves, however this won't work across DOM boundaries as there are different instances of the constructor function on each DOM, thus doing an object comparison on their constructors won't work.
This getNativeClass() function returns "undefined"
for undefined values and "null"
for null.
For all other values, the CLASSNAME
-part is extracted from [object CLASSNAME]
, which is the result of using Object.prototype.toString.call(value)
.
getAnyClass()
behaves the same as getNativeClass(), but also supports custom constructors
function getNativeClass(obj) {
if (typeof obj === "undefined") return "undefined";
if (obj === null) return "null";
return Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
}
function getAnyClass(obj) {
if (typeof obj === "undefined") return "undefined";
if (obj === null) return "null";
return obj.constructor.name;
}
getClass("") === "String";
getClass(true) === "Boolean";
getClass(0) === "Number";
getClass([]) === "Array";
getClass({}) === "Object";
getClass(null) === "null";
getAnyClass(new (function Foo(){})) === "Foo";
getAnyClass(new class Foo{}) === "Foo";
// etc...