Testing if something is a class in javascript - javascript

Hey all, I am trying to test if the argument passed into my function is a class name so that I may compare it to other classes using instanceof.
For example:
function foo(class1, class2) {
// Test to see if the parameter is a class.
if(class1 is a class)
{
//do some kind of class comparison.
if(class2 is a class)
{
if(class1 instanceof class2)
{
//...
}
}
else
{
//...
}
}
else
//...
}
Is this possible? I am having trouble googleing an answer.

There is really no such thing as a "class" in javascript -- everything but primitives are an object. Even functions are objects.
instanceof DOES work with functions though. Check out this link.
function Car(make, model, year)
{
this.make = make;
this.model = model;
this.year = year;
}
var mycar = new Car("Honda", "Accord", 1998);
var a = mycar instanceof Car; // returns true
var b = mycar instanceof Object; // returns true

Now that we have native implementations of ES6, there are "real classes". These are largely syntactic sugar for prototypal inheritance as with constructor functions, but there are subtle differences and the two are not completely interchangeable.
So far, the only way I've found is to get the .toString() of the object's prototype's constructor function and check if it starts with class OR if the object has a constructor and the .toString() of that starts with class.
Note that if your code is compiled (ie: most Babel or TypeScript setups), then this will return function... instead of class... at runtime (since classes are transpiled to constructor functions).
function isClass(obj) {
const isCtorClass = obj.constructor
&& obj.constructor.toString().substring(0, 5) === 'class'
if(obj.prototype === undefined) {
return isCtorClass
}
const isPrototypeCtorClass = obj.prototype.constructor
&& obj.prototype.constructor.toString
&& obj.prototype.constructor.toString().substring(0, 5) === 'class'
return isCtorClass || isPrototypeCtorClass
}
This will only work in native environments (Chrome, Firefox, Edge, node.js, etc.) that have implemented class for code that has not been transpiled to function.
Usage:
class A {}
class B extends A {}
isClass(A) // true
isClass(new A()) // true
isClass(B) // true
isClass(new B()) // true
function C() {}
isClass(C) // false
isClass(new C()) // false
isClass({}) // false
isClass(Date) // false
isClass(new Date()) // false
//These cases return 'true' but I'm not sure it's desired
isClass(Object.create(A)) // true
const x = {}
Object.setPrototypeOf(x, A)
isClass(x) // true
If there is a better way, I'd love to know what it is.

Here's a quick and dirty way to determine if you have a class or a function.
function myFunc() { };
class MyClass() { };
Object.getOwnPropertyNames(myFunc);
// -> [ 'length', 'name', 'arguments', 'caller', 'prototype' ]
Object.getOwnPropertyNames(MyClass);
// -> [ 'length', 'prototype', 'name' ]
So we know we have a function and not a class if arguments is a property name:
Object.getOwnPropertyNames(myFunc).includes('arguments');
// -> true
Object.getOwnPropertyNames(MyClass).includes('arguments');
// -> false
Arrow functions and aysnc functions won't have an arguments property name or a prototype. A more complete example might look like this (assuming we know the input can only be a function or a class):
function isFunction(funcOrClass) {
const propertyNames = Object.getOwnPropertyNames(funcOrClass);
return (!propertyNames.includes('prototype') || propertyNames.includes('arguments'));
}
function isFunction(funcOrClass) {
const propertyNames = Object.getOwnPropertyNames(funcOrClass);
return (!propertyNames.includes('prototype') || propertyNames.includes('arguments'));
}
console.log('class isFunction?', isFunction(class A {}));
console.log('function isFunction?', isFunction(function() {}));
console.log('async function isFunction?', isFunction(async function() {}));
console.log('arrow function isFunction?', isFunction(() => {}));

JavaScript does not have classes. It has functions which, when used with new, can be used to produce object instances. Therefore, you really want to test if class2 is a function. There are numerous ways of accomplishing this; the current (1.3) implementation of isFunction() in jQuery looks like this:
isFunction: function( obj ) {
return toString.call(obj) === "[object Function]";
},
...But see here for a rundown of the different methods:
Best method of testing for a function in JavaScript?

My solution is by checking if the function prototype has property other than constructor and checking if the function prototype is Function.prototype.
This solution can also work even after transpiled with babel, or the script is running with "use strict". But this solution will only work if the class have at least one public function, or have extend other class.
function isClass(func){
// Class constructor is also a function
if(!(func && func.constructor === Function) || func.prototype === undefined)
return false;
// This is a class that extends other class
if(Function.prototype !== Object.getPrototypeOf(func))
return true;
// Usually a function will only have 'constructor' in the prototype
return Object.getOwnPropertyNames(func.prototype).length > 1;
}
// ----Example----
class Fruit{
hello(){} // At least must have one public function
}
// Or at least it extend other class
class Pear extends Fruit{}
console.log(isClass(Fruit)); // true
console.log(isClass(Pear)); // true
console.log(isClass(function(){})); // false
console.log(isClass(function(){"use strict"})); // false
console.log(isClass(() => {})); // false
console.log(isClass({hello: 1})); // false

I know that using constructor.name on a function will return "Function" but doing so on an ES6 class instance will return the name of the class.
I do use it like this:
function isAClassInstance(item){
return item.constructor.name !== "Function" && item.constructor.name !== "Object";
}
class A {};
function B(){};
const aInstanceClass = new A();
const bFunctionInstance = new B();
const bFunction = B;
const aClass = A;
console.log(aInstanceClass.constructor.name); /*Will return "A"*/
console.log(bFunctionInstance.constructor.name); /*Will return "B"*/
console.log(A.constructor.name); /*Will return "Function"*/
console.log(B.constructor.name); /*Will return "Function"*/
console.log(bFunction.constructor.name); /*Will return "Function"*/
console.log("is A a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is B a class instance: ", isAClassInstance(aClass)); /*false*/
console.log("is aInstanceClass a class: ", isAClassInstance(aInstanceClass)); /*true*/
console.log("is bFunction a class: ", isAClassInstance(bFunction)); /*false*/
console.log("is bFunctionInstance a class: ", isAClassInstance(bFunctionInstance)); /*true*/
For the cases i used this worked perfectly.
note: since a class is technically a function doing new A() and new B() are both the same thus returning the same result from isAClassInstance.
The only way to dinstinguish a function from a class is to not use new on a function and keep this keyword for class only.
Hope this will help :).

Try this one:
function isClass(C) {
return typeof C === "function" && C.prototype !== undefined;
}
Every class is internally just a function that creates instances of this class, plus a prototype property that's assigned to [[Prototype]] of newly created objects to make them behave like instances of this particular class. So, to check if C is a class, you need to check these two things - this is what the isClass() code above does.
Note that all functions declared with function keyword can also be used with new as constructors, and inside instanceof tests. They're equivalent to classes, and have a prototype likewise, so every function of this type is (correctly) recognized as a class by the isClass() function above.
console.log(isClass(Object)); // true
console.log(isClass(Number)); // true
console.log(isClass({a:1})); // false
console.log(isClass(123)); // false
console.log(isClass("123")); // false
class A {}
class B extends A {}
console.log(isClass(A)); // true
console.log(isClass(B)); // true
console.log(isClass(new B())); // false
function f(name) { this.name = name; }
console.log(isClass(f)); // true

Hey just updating an old thread I took one of the above answers and made it work with all the predefined classes in javascript. eg. String, Map, extra
Original:
function isClass(obj) {
const isCtorClass = obj.constructor
&& obj.constructor.toString().substring(0, 5) === 'class'
if(obj.prototype === undefined) {
return isCtorClass
}
const isPrototypeCtorClass = obj.prototype.constructor
&& obj.prototype.constructor.toString
&& obj.prototype.constructor.toString().substring(0, 5) === 'class'
return isCtorClass || isPrototypeCtorClass
}
New:
export const isClass = (obj) => {
if (obj == null || typeof obj == "undefined") { return false; }
const isCtorClass = obj.constructor
&& obj.constructor.toString().substring(0, 5) === 'class'
const isNativeCtorClass= obj.constructor &&
obj.constructor.name != "Function" &&
obj.constructor.name in global;
if (obj.prototype === undefined) {
return isCtorClass || isNativeCtorClass
}
const isPrototypeCtorClass = obj.prototype.constructor
&& obj.prototype.constructor.toString
&& obj.prototype.constructor.toString().substring(0, 5) === 'class'
const isNativePrototypeCtorClass = obj.prototype.constructor.name in global && (
global[obj.prototype.constructor.name] == obj.constructor ||
global[obj.prototype.constructor.name] == obj
);
return isCtorClass || isPrototypeCtorClass || isNativeCtorClass || isNativePrototypeCtorClass
}
This checks the object in the global javascript object to check if it's a currently registered object.
Let me know if this would break for some use cases but it works for me.
isClass(function test() {}) // false
isClass(() => {}) // false
isClass(function String() {}) // false
isClass(String) // true
isClass("") // true
isClass(0) // true
isClass(class Test {}) // true
isClass(new Number(0)) // true
isClass(new (class Test{})()) // true

After reviewing the answers here I built out my own internal solution. I wanted to ensure that it only returns true if its a Class and not an instance of a class and I wanted distinguish between ES6 and classic / builtin (eg. Array) classes.
This solution should work for anything you throw at it. Please let me know if you find any exceptions.
// Will only return true for ES6 Class definitions
function isES6Class(o) {
return isClass(o, {es6: true})
}
// Will return any class unless {es6:true} is passed (see isES6Class)
function isClass(o, opts) {
if(!o)return false
if(!o.prototype) return false
if(__cls(o.constructor) || __cls(o.prototype.constructor)) return true
if(opts && opts.es6) return false
// Old school or builtin class
// If is function that has name with first letter capitalized
if((typeof o) === 'function'){
var s = funcName(o)
if (s.length > 0){
var i = s.charCodeAt(0)
if (i > 64 && i < 91){ return true }
}
}
return false
function __cls(v){
return v.toString && v.toString().indexOf('class')===0
}
}
// helper
var RE_FUNC_DEF = new RegExp("^\\s*function\\s*(\\S*)\\s*\\((.*)\\)");
function funcName(f){
if (!f) return("(funcName() - f is Nothing!)")
if(!_.isFunction(f))return("(funcName() - f is not a function!) - f = " + String(f))
var s = f.toString(), m = s.match(RE_FUNC_DEF)
if (m && m.length > 1) return m[1]
return null
}

I haven't found any 100% certain way to figure out
if something is a class and not a function. The
accepted answer above works in most cases but if
someone redefines the method toString() of their
class it may break in that case. Why would they
ever redefine toString()? I don't know, ask them
if they are still around :-)
So instead I took the approach of defining this
function:
function isClass(v)
{ if (typeof v !== "function")
{ return false;
}
if ( typeof v.isClass === "function" &&
v.isClass()
)
{ return true;
}
}
This means I can mark my own classes as
being classes I recognize as classes by
giving them the static method isClass()
which returns true. If such classes have
subclasses the subclasses inherit the
method and are thus automatically recognized
as "classes" as well.
If I need to work with someone else's
classes which does not have this method
I might first subclass their class so
that my subclass is like their class
except it also has the isClass() -method.
I hope the next version of EcmaScript will
remedy this lack of standardized solution
but for now this is the best I can do.
It has the additional benefit that I might
in fact give the method isClass() to some
of my non-class-functions as well, which are
not classes proper, and then be able to
treat such functions as if they were classes,
for whatever reason I might want to.

Related

How to get the class from an instantiation in JS? [duplicate]

I created a JavaScript object, but how I can determine the class of that object?
I want something similar to Java's .getClass() method.
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...
We can read Class's name of an instance by just doing 'instance.constructor.name' like in this example:
class Person {
type = "developer";
}
let p = new Person();
p.constructor.name // Person
To get the "pseudo class", you can get the constructor function, by
obj.constructor
assuming the constructor is set correctly when you do the inheritance -- which is by something like:
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
and these two lines, together with:
var woofie = new Dog()
will make woofie.constructor point to Dog. Note that Dog is a constructor function, and is a Function object. But you can do if (woofie.constructor === Dog) { ... }.
If you want to get the class name as a string, I found the following working well:
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
function getObjectClass(obj) {
if (obj && obj.constructor && obj.constructor.toString) {
var arr = obj.constructor.toString().match(
/function\s*(\w+)/);
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
}
It gets to the constructor function, converts it to string, and extracts the name of the constructor function.
Note that obj.constructor.name could have worked well, but it is not standard. It is on Chrome and Firefox, but not on IE, including IE 9 or IE 10 RTM.
You can get a reference to the constructor function which created the object by using the constructor property:
function MyObject(){
}
var obj = new MyObject();
obj.constructor; // MyObject
If you need to confirm the type of an object at runtime you can use the instanceof operator:
obj instanceof MyObject // true
i had a situation to work generic now and used this:
class Test {
// your class definition
}
nameByType = function(type){
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test));
thats the only way i found to get the class name by type input if you don't have a instance of an object.
(written in ES2017)
dot notation also works fine
console.log(Test.prototype.constructor.name); // returns "Test"
In keeping with its unbroken record of backwards-compatibility, ECMAScript 6, JavaScript still doesn't have a class type (though not everyone understands this). It does have a class keyword as part of its class syntax for creating prototypes—but still no thing called class. JavaScript is not now and has never been a classical OOP language. Speaking of JS in terms of class is only either misleading or a sign of not yet grokking prototypical inheritance (just keeping it real).
That means this.constructor is still a great way to get a reference to the constructor function. And this.constructor.prototype is the way to access the prototype itself. Since this isn't Java, it's not a class. It's the prototype object your instance was instantiated from. Here is an example using the ES6 syntactic sugar for creating a prototype chain:
class Foo {
get foo () {
console.info(this.constructor, this.constructor.name)
return 'foo'
}
}
class Bar extends Foo {
get foo () {
console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))
return `${super.foo} + bar`
}
}
const bar = new Bar()
console.dir(bar.foo)
This is what that outputs using babel-node:
> $ babel-node ./foo.js ⬡ 6.2.0 [±master ●]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'
There you have it! In 2016, there's a class keyword in JavaScript, but still no class type. this.constructor is the best way to get the constructor function, this.constructor.prototype the best way to get access to the prototype itself.
For Javascript Classes in ES6 you can use object.constructor. In the example class below the getClass() method returns the ES6 class as you would expect:
var Cat = class {
meow() {
console.log("meow!");
}
getClass() {
return this.constructor;
}
}
var fluffy = new Cat();
...
var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();
ruffles.meow(); // "meow!"
If you instantiate the class from the getClass method make sure you wrap it in brackets e.g. ruffles = new ( fluffy.getClass() )( args... );
If you need to not only GET class but also EXTEND it from having just an instance, write:
let's have
class A{
constructor(name){
this.name = name
}
};
const a1 = new A('hello a1');
so to extend A having the instance only use:
const a2 = new (Object.getPrototypeOf(a1)).constructor('hello from a2')
// the analog of const a2 = new A()
console.log(a2.name)//'hello from a2'
I find object.constructor.toString() return [object objectClass] in IE ,rather than function objectClass () {} returned in chome. So,I think the code in http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects may not work well in IE.And I fixed the code as follows:
code:
var getObjectClass = function (obj) {
if (obj && obj.constructor && obj.constructor.toString()) {
/*
* for browsers which have name property in the constructor
* of the object,such as chrome
*/
if(obj.constructor.name) {
return obj.constructor.name;
}
var str = obj.constructor.toString();
/*
* executed if the return of object.constructor.toString() is
* "[object objectClass]"
*/
if(str.charAt(0) == '[')
{
var arr = str.match(/\[\w+\s*(\w+)\]/);
} else {
/*
* executed if the return of object.constructor.toString() is
* "function objectClass () {}"
* for IE Firefox
*/
var arr = str.match(/function\s*(\w+)/);
}
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
};
In javascript, there are no classes, but I think that you want the constructor name and obj.constructor.toString() will tell you what you need.
getClass() function using constructor.prototype.name
I found a way to access the class that is much cleaner than some of the solutions above; here it is.
function getClass(obj) {
// if the type is not an object return the type
if((let type = typeof obj) !== 'object') return type;
//otherwise, access the class using obj.constructor.name
else return obj.constructor.name;
}
How it works
the constructor has a property called name accessing that will give you the class name.
cleaner version of the code:
function getClass(obj) {
// if the type is not an object return the type
let type = typeof obj
if((type !== 'object')) {
return type;
} else { //otherwise, access the class using obj.constructor.name
return obj.constructor.name;
}
}
Agree with dfa, that's why i consider the prototye as the class when no named class found
Here is an upgraded function of the one posted by Eli Grey, to match my way of mind
function what(obj){
if(typeof(obj)==="undefined")return "undefined";
if(obj===null)return "Null";
var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
if(res==="Object"){
res = obj.constructor.name;
if(typeof(res)!='string' || res.length==0){
if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects
if(obj instanceof Array)return "Array";// Array prototype is very sneaky
return "Object";
}
}
return res;
}
Here's a implementation of getClass() and getInstance()
You are able to get a reference for an Object's class using this.constructor.
From an instance context:
function A() {
this.getClass = function() {
return this.constructor;
}
this.getNewInstance = function() {
return new this.constructor;
}
}
var a = new A();
console.log(a.getClass()); // function A { // etc... }
// you can even:
var b = new (a.getClass());
console.log(b instanceof A); // true
var c = a.getNewInstance();
console.log(c instanceof A); // true
From static context:
function A() {};
A.getClass = function() {
return this;
}
A.getInstance() {
return new this;
}
Don't use o.constructor because it can be changed by the object content. Instead, use Object.getPrototypeOf()?.constructor.
const fakedArray = JSON.parse('{ "constructor": { "name": "Array" } }');
// returns 'Array', which is faked.
fakedArray.constructor.name;
// returns 'Object' as expected
Object.getPrototypeOf(fakedArray)?.constructor?.name;
I suggest using Object.prototype.constructor.name:
Object.defineProperty(Object.prototype, "getClass", {
value: function() {
return this.constructor.name;
}
});
var x = new DOMParser();
console.log(x.getClass()); // `DOMParser'
var y = new Error("");
console.log(y.getClass()); // `Error'
You can also do something like this
class Hello {
constructor(){
}
}
function isClass (func) {
return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func))
}
console.log(isClass(Hello))
This will tell you if the input is class or not
If you have access to an instance of the class Foo (say foo = new Foo()) then there is exactly one way to get access to the the class from the instance: foo.Contructor in Javascript = foo.getClass() in Java.
eval() is another way, but since eval() is never recommended and works for everything (analogous to Java reflection), that answer is not recommended. foo.Constructor = Foo
Javascript is a class-less languages: there are no classes that defines the behaviour of a class statically as in Java. JavaScript uses prototypes instead of classes for defining object properties, including methods, and inheritance. It is possible to simulate many class-based features with prototypes in JavaScript.
Question seems already answered but the OP wants to access the class of and object, just like we do in Java and the selected answer is not enough (imho).
With the following explanation, we can get a class of an object(it's actually called prototype in javascript).
var arr = new Array('red', 'green', 'blue');
var arr2 = new Array('white', 'black', 'orange');
You can add a property like this:
Object.defineProperty(arr,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
But .last property will only be available to 'arr' object which is instantiated from Array prototype. So, in order to have the .last property to be available for all objects instantiated from Array prototype, we have to define the .last property for Array prototype:
Object.defineProperty(Array.prototype,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
The problem here is, you have to know which object type (prototype) the 'arr' and 'arr2' variables belongs to! In other words, if you don't know class type (prototype) of the 'arr' object, then you won't be able to define a property for them. In the above example, we know arr is instance of the Array object, that's why we used Array.prototype to define a property for Array. But what if we didn't know the class(prototype) of the 'arr'?
Object.defineProperty(arr.__proto__,'last2', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
As you can see, without knowing that 'arr' is an Array, we can add a new property just bu referring the class of the 'arr' by using 'arr.__proto__'.
We accessed the prototype of the 'arr' without knowing that it's an instance of Array and I think that's what OP asked.
There is one another technique to identify your class
You can store ref to your class in instance like below.
class MyClass {
static myStaticProperty = 'default';
constructor() {
this.__class__ = new.target;
this.showStaticProperty = function() {
console.log(this.__class__.myStaticProperty);
}
}
}
class MyChildClass extends MyClass {
static myStaticProperty = 'custom';
}
let myClass = new MyClass();
let child = new MyChildClass();
myClass.showStaticProperty(); // default
child.showStaticProperty(); // custom
myClass.__class__ === MyClass; // true
child.__class__ === MyClass; // false
child.__class__ === MyChildClass; // true

How to get the class name for an object in Javascript [duplicate]

I created a JavaScript object, but how I can determine the class of that object?
I want something similar to Java's .getClass() method.
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...
We can read Class's name of an instance by just doing 'instance.constructor.name' like in this example:
class Person {
type = "developer";
}
let p = new Person();
p.constructor.name // Person
To get the "pseudo class", you can get the constructor function, by
obj.constructor
assuming the constructor is set correctly when you do the inheritance -- which is by something like:
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
and these two lines, together with:
var woofie = new Dog()
will make woofie.constructor point to Dog. Note that Dog is a constructor function, and is a Function object. But you can do if (woofie.constructor === Dog) { ... }.
If you want to get the class name as a string, I found the following working well:
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
function getObjectClass(obj) {
if (obj && obj.constructor && obj.constructor.toString) {
var arr = obj.constructor.toString().match(
/function\s*(\w+)/);
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
}
It gets to the constructor function, converts it to string, and extracts the name of the constructor function.
Note that obj.constructor.name could have worked well, but it is not standard. It is on Chrome and Firefox, but not on IE, including IE 9 or IE 10 RTM.
You can get a reference to the constructor function which created the object by using the constructor property:
function MyObject(){
}
var obj = new MyObject();
obj.constructor; // MyObject
If you need to confirm the type of an object at runtime you can use the instanceof operator:
obj instanceof MyObject // true
i had a situation to work generic now and used this:
class Test {
// your class definition
}
nameByType = function(type){
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test));
thats the only way i found to get the class name by type input if you don't have a instance of an object.
(written in ES2017)
dot notation also works fine
console.log(Test.prototype.constructor.name); // returns "Test"
In keeping with its unbroken record of backwards-compatibility, ECMAScript 6, JavaScript still doesn't have a class type (though not everyone understands this). It does have a class keyword as part of its class syntax for creating prototypes—but still no thing called class. JavaScript is not now and has never been a classical OOP language. Speaking of JS in terms of class is only either misleading or a sign of not yet grokking prototypical inheritance (just keeping it real).
That means this.constructor is still a great way to get a reference to the constructor function. And this.constructor.prototype is the way to access the prototype itself. Since this isn't Java, it's not a class. It's the prototype object your instance was instantiated from. Here is an example using the ES6 syntactic sugar for creating a prototype chain:
class Foo {
get foo () {
console.info(this.constructor, this.constructor.name)
return 'foo'
}
}
class Bar extends Foo {
get foo () {
console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))
return `${super.foo} + bar`
}
}
const bar = new Bar()
console.dir(bar.foo)
This is what that outputs using babel-node:
> $ babel-node ./foo.js ⬡ 6.2.0 [±master ●]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'
There you have it! In 2016, there's a class keyword in JavaScript, but still no class type. this.constructor is the best way to get the constructor function, this.constructor.prototype the best way to get access to the prototype itself.
For Javascript Classes in ES6 you can use object.constructor. In the example class below the getClass() method returns the ES6 class as you would expect:
var Cat = class {
meow() {
console.log("meow!");
}
getClass() {
return this.constructor;
}
}
var fluffy = new Cat();
...
var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();
ruffles.meow(); // "meow!"
If you instantiate the class from the getClass method make sure you wrap it in brackets e.g. ruffles = new ( fluffy.getClass() )( args... );
If you need to not only GET class but also EXTEND it from having just an instance, write:
let's have
class A{
constructor(name){
this.name = name
}
};
const a1 = new A('hello a1');
so to extend A having the instance only use:
const a2 = new (Object.getPrototypeOf(a1)).constructor('hello from a2')
// the analog of const a2 = new A()
console.log(a2.name)//'hello from a2'
I find object.constructor.toString() return [object objectClass] in IE ,rather than function objectClass () {} returned in chome. So,I think the code in http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects may not work well in IE.And I fixed the code as follows:
code:
var getObjectClass = function (obj) {
if (obj && obj.constructor && obj.constructor.toString()) {
/*
* for browsers which have name property in the constructor
* of the object,such as chrome
*/
if(obj.constructor.name) {
return obj.constructor.name;
}
var str = obj.constructor.toString();
/*
* executed if the return of object.constructor.toString() is
* "[object objectClass]"
*/
if(str.charAt(0) == '[')
{
var arr = str.match(/\[\w+\s*(\w+)\]/);
} else {
/*
* executed if the return of object.constructor.toString() is
* "function objectClass () {}"
* for IE Firefox
*/
var arr = str.match(/function\s*(\w+)/);
}
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
};
In javascript, there are no classes, but I think that you want the constructor name and obj.constructor.toString() will tell you what you need.
getClass() function using constructor.prototype.name
I found a way to access the class that is much cleaner than some of the solutions above; here it is.
function getClass(obj) {
// if the type is not an object return the type
if((let type = typeof obj) !== 'object') return type;
//otherwise, access the class using obj.constructor.name
else return obj.constructor.name;
}
How it works
the constructor has a property called name accessing that will give you the class name.
cleaner version of the code:
function getClass(obj) {
// if the type is not an object return the type
let type = typeof obj
if((type !== 'object')) {
return type;
} else { //otherwise, access the class using obj.constructor.name
return obj.constructor.name;
}
}
Agree with dfa, that's why i consider the prototye as the class when no named class found
Here is an upgraded function of the one posted by Eli Grey, to match my way of mind
function what(obj){
if(typeof(obj)==="undefined")return "undefined";
if(obj===null)return "Null";
var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
if(res==="Object"){
res = obj.constructor.name;
if(typeof(res)!='string' || res.length==0){
if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects
if(obj instanceof Array)return "Array";// Array prototype is very sneaky
return "Object";
}
}
return res;
}
Here's a implementation of getClass() and getInstance()
You are able to get a reference for an Object's class using this.constructor.
From an instance context:
function A() {
this.getClass = function() {
return this.constructor;
}
this.getNewInstance = function() {
return new this.constructor;
}
}
var a = new A();
console.log(a.getClass()); // function A { // etc... }
// you can even:
var b = new (a.getClass());
console.log(b instanceof A); // true
var c = a.getNewInstance();
console.log(c instanceof A); // true
From static context:
function A() {};
A.getClass = function() {
return this;
}
A.getInstance() {
return new this;
}
Don't use o.constructor because it can be changed by the object content. Instead, use Object.getPrototypeOf()?.constructor.
const fakedArray = JSON.parse('{ "constructor": { "name": "Array" } }');
// returns 'Array', which is faked.
fakedArray.constructor.name;
// returns 'Object' as expected
Object.getPrototypeOf(fakedArray)?.constructor?.name;
I suggest using Object.prototype.constructor.name:
Object.defineProperty(Object.prototype, "getClass", {
value: function() {
return this.constructor.name;
}
});
var x = new DOMParser();
console.log(x.getClass()); // `DOMParser'
var y = new Error("");
console.log(y.getClass()); // `Error'
You can also do something like this
class Hello {
constructor(){
}
}
function isClass (func) {
return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func))
}
console.log(isClass(Hello))
This will tell you if the input is class or not
If you have access to an instance of the class Foo (say foo = new Foo()) then there is exactly one way to get access to the the class from the instance: foo.Contructor in Javascript = foo.getClass() in Java.
eval() is another way, but since eval() is never recommended and works for everything (analogous to Java reflection), that answer is not recommended. foo.Constructor = Foo
Javascript is a class-less languages: there are no classes that defines the behaviour of a class statically as in Java. JavaScript uses prototypes instead of classes for defining object properties, including methods, and inheritance. It is possible to simulate many class-based features with prototypes in JavaScript.
Question seems already answered but the OP wants to access the class of and object, just like we do in Java and the selected answer is not enough (imho).
With the following explanation, we can get a class of an object(it's actually called prototype in javascript).
var arr = new Array('red', 'green', 'blue');
var arr2 = new Array('white', 'black', 'orange');
You can add a property like this:
Object.defineProperty(arr,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
But .last property will only be available to 'arr' object which is instantiated from Array prototype. So, in order to have the .last property to be available for all objects instantiated from Array prototype, we have to define the .last property for Array prototype:
Object.defineProperty(Array.prototype,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
The problem here is, you have to know which object type (prototype) the 'arr' and 'arr2' variables belongs to! In other words, if you don't know class type (prototype) of the 'arr' object, then you won't be able to define a property for them. In the above example, we know arr is instance of the Array object, that's why we used Array.prototype to define a property for Array. But what if we didn't know the class(prototype) of the 'arr'?
Object.defineProperty(arr.__proto__,'last2', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
As you can see, without knowing that 'arr' is an Array, we can add a new property just bu referring the class of the 'arr' by using 'arr.__proto__'.
We accessed the prototype of the 'arr' without knowing that it's an instance of Array and I think that's what OP asked.
There is one another technique to identify your class
You can store ref to your class in instance like below.
class MyClass {
static myStaticProperty = 'default';
constructor() {
this.__class__ = new.target;
this.showStaticProperty = function() {
console.log(this.__class__.myStaticProperty);
}
}
}
class MyChildClass extends MyClass {
static myStaticProperty = 'custom';
}
let myClass = new MyClass();
let child = new MyChildClass();
myClass.showStaticProperty(); // default
child.showStaticProperty(); // custom
myClass.__class__ === MyClass; // true
child.__class__ === MyClass; // false
child.__class__ === MyChildClass; // true

Analysing three.js

I would like to analyse the classes of three.js library. I have a function, that can find out, if the given class relaying on another class or not.
function getParent (className) {
var parent = null;
var object = new THREE[className]();
for (var a in THREE) {
if (typeof THREE[a] === "function" && object instanceof THREE[a] && a !== className) {
parent = a;
break
}
}
return(parent)
}
And I also would like to have a function that returns 2 arrays. One with properties and one with methods. When iterating over "object", I can determine what kind of the member is, but how can i check that, it is not inherited?
If parent is exist and I store a reference of it, negating the result of parentObject.hasOwnProperty does not work.
for (var member in object) {
if (typeof object[member] === "function") {
if (!parentObject.hasOwnProperty(member)) {
methods.push(member)
}
}
else {
//...
}
}
hasOwnProperty does not check through the prototype chain, so if it returns true you know that the property was not inherited. You don't need to check the parent object members.
if (object.hasOwnProperty(member))
methods.push(member)
else
...
For more details - Object.prototype.hasOwnProperty()
I hope you have understood how classes work in JavaScript and how inheritance is done for them.
for (var a in THREE) {
if (typeof THREE[a] === "function" && object instanceof THREE[a] && a !== className) {
parent = a;
That does not work for multi-level inheritance. Better use something like
function getParent (className) {
var proto = THREE[className].prototype,
parproto = Object.getPrototypeOf(proto);
for (var a in THREE)
if (typeof THREE[a] === "function" && THREE[a].prototype === parproto)
return a;
return null;
}
But notice that this only detects prototypical inheritance, no such things like mixin inheritance. Since prototypical inheritance is done using the standard pattern in Three.js, you might as well just search the code
I can determine what kind of the member is, but how can i check that, it is not inherited? If parent is exist and I store a reference of it, negating the result of parentObject.hasOwnProperty does not work.
I don't know what parentObject is in your case, but especially for methods it might be likely that an instance does inherit the method from its prototype, i.e. does not have it as an own property.
You better do something like this:
function describeProperties(className) {
try {
var o = new THREE[className](), // do you know appropriate arguments?
p = Object.getPrototypeOf(o);
} catch(e) { // probably constructor call was not successful
o = p = THREE[className].prototype;
}
var props = {};
for (var prop in o) {
var desc = [];
desc.push( (typeof o[prop] == "function") ? "method" : "value");
if (!(prop in p)) // does not appear on the prototype
desc.push("instance-specific") // so was added in constructor
if (o !== p && o.hasOwnProperty(prop) && prop in p)
desc.push("defaulted");
if (prop in Object.getPrototypeOf(p)) {
desc.push("inherited") // from parent class
if (p.hasOwnProperty(prop)) // but also in own prototype
desc.push("overwritten");
}
props[prop] = desc.join(" ");
}
return props;
}

How to get a JavaScript object's class?

I created a JavaScript object, but how I can determine the class of that object?
I want something similar to Java's .getClass() method.
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...
We can read Class's name of an instance by just doing 'instance.constructor.name' like in this example:
class Person {
type = "developer";
}
let p = new Person();
p.constructor.name // Person
To get the "pseudo class", you can get the constructor function, by
obj.constructor
assuming the constructor is set correctly when you do the inheritance -- which is by something like:
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
and these two lines, together with:
var woofie = new Dog()
will make woofie.constructor point to Dog. Note that Dog is a constructor function, and is a Function object. But you can do if (woofie.constructor === Dog) { ... }.
If you want to get the class name as a string, I found the following working well:
http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects
function getObjectClass(obj) {
if (obj && obj.constructor && obj.constructor.toString) {
var arr = obj.constructor.toString().match(
/function\s*(\w+)/);
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
}
It gets to the constructor function, converts it to string, and extracts the name of the constructor function.
Note that obj.constructor.name could have worked well, but it is not standard. It is on Chrome and Firefox, but not on IE, including IE 9 or IE 10 RTM.
You can get a reference to the constructor function which created the object by using the constructor property:
function MyObject(){
}
var obj = new MyObject();
obj.constructor; // MyObject
If you need to confirm the type of an object at runtime you can use the instanceof operator:
obj instanceof MyObject // true
i had a situation to work generic now and used this:
class Test {
// your class definition
}
nameByType = function(type){
return type.prototype["constructor"]["name"];
};
console.log(nameByType(Test));
thats the only way i found to get the class name by type input if you don't have a instance of an object.
(written in ES2017)
dot notation also works fine
console.log(Test.prototype.constructor.name); // returns "Test"
In keeping with its unbroken record of backwards-compatibility, ECMAScript 6, JavaScript still doesn't have a class type (though not everyone understands this). It does have a class keyword as part of its class syntax for creating prototypes—but still no thing called class. JavaScript is not now and has never been a classical OOP language. Speaking of JS in terms of class is only either misleading or a sign of not yet grokking prototypical inheritance (just keeping it real).
That means this.constructor is still a great way to get a reference to the constructor function. And this.constructor.prototype is the way to access the prototype itself. Since this isn't Java, it's not a class. It's the prototype object your instance was instantiated from. Here is an example using the ES6 syntactic sugar for creating a prototype chain:
class Foo {
get foo () {
console.info(this.constructor, this.constructor.name)
return 'foo'
}
}
class Bar extends Foo {
get foo () {
console.info('[THIS]', this.constructor, this.constructor.name, Object.getOwnPropertyNames(this.constructor.prototype))
console.info('[SUPER]', super.constructor, super.constructor.name, Object.getOwnPropertyNames(super.constructor.prototype))
return `${super.foo} + bar`
}
}
const bar = new Bar()
console.dir(bar.foo)
This is what that outputs using babel-node:
> $ babel-node ./foo.js ⬡ 6.2.0 [±master ●]
[THIS] [Function: Bar] 'Bar' [ 'constructor', 'foo' ]
[SUPER] [Function: Foo] 'Foo' [ 'constructor', 'foo' ]
[Function: Bar] 'Bar'
'foo + bar'
There you have it! In 2016, there's a class keyword in JavaScript, but still no class type. this.constructor is the best way to get the constructor function, this.constructor.prototype the best way to get access to the prototype itself.
For Javascript Classes in ES6 you can use object.constructor. In the example class below the getClass() method returns the ES6 class as you would expect:
var Cat = class {
meow() {
console.log("meow!");
}
getClass() {
return this.constructor;
}
}
var fluffy = new Cat();
...
var AlsoCat = fluffy.getClass();
var ruffles = new AlsoCat();
ruffles.meow(); // "meow!"
If you instantiate the class from the getClass method make sure you wrap it in brackets e.g. ruffles = new ( fluffy.getClass() )( args... );
If you need to not only GET class but also EXTEND it from having just an instance, write:
let's have
class A{
constructor(name){
this.name = name
}
};
const a1 = new A('hello a1');
so to extend A having the instance only use:
const a2 = new (Object.getPrototypeOf(a1)).constructor('hello from a2')
// the analog of const a2 = new A()
console.log(a2.name)//'hello from a2'
I find object.constructor.toString() return [object objectClass] in IE ,rather than function objectClass () {} returned in chome. So,I think the code in http://blog.magnetiq.com/post/514962277/finding-out-class-names-of-javascript-objects may not work well in IE.And I fixed the code as follows:
code:
var getObjectClass = function (obj) {
if (obj && obj.constructor && obj.constructor.toString()) {
/*
* for browsers which have name property in the constructor
* of the object,such as chrome
*/
if(obj.constructor.name) {
return obj.constructor.name;
}
var str = obj.constructor.toString();
/*
* executed if the return of object.constructor.toString() is
* "[object objectClass]"
*/
if(str.charAt(0) == '[')
{
var arr = str.match(/\[\w+\s*(\w+)\]/);
} else {
/*
* executed if the return of object.constructor.toString() is
* "function objectClass () {}"
* for IE Firefox
*/
var arr = str.match(/function\s*(\w+)/);
}
if (arr && arr.length == 2) {
return arr[1];
}
}
return undefined;
};
In javascript, there are no classes, but I think that you want the constructor name and obj.constructor.toString() will tell you what you need.
getClass() function using constructor.prototype.name
I found a way to access the class that is much cleaner than some of the solutions above; here it is.
function getClass(obj) {
// if the type is not an object return the type
if((let type = typeof obj) !== 'object') return type;
//otherwise, access the class using obj.constructor.name
else return obj.constructor.name;
}
How it works
the constructor has a property called name accessing that will give you the class name.
cleaner version of the code:
function getClass(obj) {
// if the type is not an object return the type
let type = typeof obj
if((type !== 'object')) {
return type;
} else { //otherwise, access the class using obj.constructor.name
return obj.constructor.name;
}
}
Agree with dfa, that's why i consider the prototye as the class when no named class found
Here is an upgraded function of the one posted by Eli Grey, to match my way of mind
function what(obj){
if(typeof(obj)==="undefined")return "undefined";
if(obj===null)return "Null";
var res = Object.prototype.toString.call(obj).match(/^\[object\s(.*)\]$/)[1];
if(res==="Object"){
res = obj.constructor.name;
if(typeof(res)!='string' || res.length==0){
if(obj instanceof jQuery)return "jQuery";// jQuery build stranges Objects
if(obj instanceof Array)return "Array";// Array prototype is very sneaky
return "Object";
}
}
return res;
}
Here's a implementation of getClass() and getInstance()
You are able to get a reference for an Object's class using this.constructor.
From an instance context:
function A() {
this.getClass = function() {
return this.constructor;
}
this.getNewInstance = function() {
return new this.constructor;
}
}
var a = new A();
console.log(a.getClass()); // function A { // etc... }
// you can even:
var b = new (a.getClass());
console.log(b instanceof A); // true
var c = a.getNewInstance();
console.log(c instanceof A); // true
From static context:
function A() {};
A.getClass = function() {
return this;
}
A.getInstance() {
return new this;
}
Don't use o.constructor because it can be changed by the object content. Instead, use Object.getPrototypeOf()?.constructor.
const fakedArray = JSON.parse('{ "constructor": { "name": "Array" } }');
// returns 'Array', which is faked.
fakedArray.constructor.name;
// returns 'Object' as expected
Object.getPrototypeOf(fakedArray)?.constructor?.name;
I suggest using Object.prototype.constructor.name:
Object.defineProperty(Object.prototype, "getClass", {
value: function() {
return this.constructor.name;
}
});
var x = new DOMParser();
console.log(x.getClass()); // `DOMParser'
var y = new Error("");
console.log(y.getClass()); // `Error'
You can also do something like this
class Hello {
constructor(){
}
}
function isClass (func) {
return typeof func === 'function' && /^class\s/.test(Function.prototype.toString.call(func))
}
console.log(isClass(Hello))
This will tell you if the input is class or not
If you have access to an instance of the class Foo (say foo = new Foo()) then there is exactly one way to get access to the the class from the instance: foo.Contructor in Javascript = foo.getClass() in Java.
eval() is another way, but since eval() is never recommended and works for everything (analogous to Java reflection), that answer is not recommended. foo.Constructor = Foo
Javascript is a class-less languages: there are no classes that defines the behaviour of a class statically as in Java. JavaScript uses prototypes instead of classes for defining object properties, including methods, and inheritance. It is possible to simulate many class-based features with prototypes in JavaScript.
Question seems already answered but the OP wants to access the class of and object, just like we do in Java and the selected answer is not enough (imho).
With the following explanation, we can get a class of an object(it's actually called prototype in javascript).
var arr = new Array('red', 'green', 'blue');
var arr2 = new Array('white', 'black', 'orange');
You can add a property like this:
Object.defineProperty(arr,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
But .last property will only be available to 'arr' object which is instantiated from Array prototype. So, in order to have the .last property to be available for all objects instantiated from Array prototype, we have to define the .last property for Array prototype:
Object.defineProperty(Array.prototype,'last', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
The problem here is, you have to know which object type (prototype) the 'arr' and 'arr2' variables belongs to! In other words, if you don't know class type (prototype) of the 'arr' object, then you won't be able to define a property for them. In the above example, we know arr is instance of the Array object, that's why we used Array.prototype to define a property for Array. But what if we didn't know the class(prototype) of the 'arr'?
Object.defineProperty(arr.__proto__,'last2', {
get: function(){
return this[this.length -1];
}
});
console.log(arr.last) // blue
console.log(arr2.last) // orange
As you can see, without knowing that 'arr' is an Array, we can add a new property just bu referring the class of the 'arr' by using 'arr.__proto__'.
We accessed the prototype of the 'arr' without knowing that it's an instance of Array and I think that's what OP asked.
There is one another technique to identify your class
You can store ref to your class in instance like below.
class MyClass {
static myStaticProperty = 'default';
constructor() {
this.__class__ = new.target;
this.showStaticProperty = function() {
console.log(this.__class__.myStaticProperty);
}
}
}
class MyChildClass extends MyClass {
static myStaticProperty = 'custom';
}
let myClass = new MyClass();
let child = new MyChildClass();
myClass.showStaticProperty(); // default
child.showStaticProperty(); // custom
myClass.__class__ === MyClass; // true
child.__class__ === MyClass; // false
child.__class__ === MyChildClass; // true

Get the name of an object's type

Is there a JavaScript equivalent of Java's class.getName()?
Is there a JavaScript equivalent of Java's class.getName()?
No.
ES2015 Update: the name of class Foo {} is Foo.name. The name of thing's class, regardless of thing's type, is thing.constructor.name. Builtin constructors in an ES2015 environment have the correct name property; for instance (2).constructor.name is "Number".
But here are various hacks that all fall down in one way or another:
Here is a hack that will do what you need - be aware that it modifies the Object's prototype, something people frown upon (usually for good reason)
Object.prototype.getName = function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
};
Now, all of your objects will have the function, getName(), that will return the name of the constructor as a string. I have tested this in FF3 and IE7, I can't speak for other implementations.
If you don't want to do that, here is a discussion on the various ways of determining types in JavaScript...
I recently updated this to be a bit more exhaustive, though it is hardly that. Corrections welcome...
Using the constructor property...
Every object has a value for its constructor property, but depending on how that object was constructed as well as what you want to do with that value, it may or may not be useful.
Generally speaking, you can use the constructor property to test the type of the object like so:
var myArray = [1,2,3];
(myArray.constructor == Array); // true
So, that works well enough for most needs. That said...
Caveats
Will not work AT ALL in many cases
This pattern, though broken, is quite common:
function Thingy() {
}
Thingy.prototype = {
method1: function() {
},
method2: function() {
}
};
Objects constructed via new Thingy will have a constructor property that points to Object, not Thingy. So we fall right at the outset; you simply cannot trust constructor in a codebase that you don't control.
Multiple Inheritance
An example where it isn't as obvious is using multiple inheritance:
function a() { this.foo = 1;}
function b() { this.bar = 2; }
b.prototype = new a(); // b inherits from a
Things now don't work as you might expect them to:
var f = new b(); // instantiate a new object with the b constructor
(f.constructor == b); // false
(f.constructor == a); // true
So, you might get unexpected results if the object your testing has a different object set as its prototype. There are ways around this outside the scope of this discussion.
There are other uses for the constructor property, some of them interesting, others not so much; for now we will not delve into those uses since it isn't relevant to this discussion.
Will not work cross-frame and cross-window
Using .constructor for type checking will break when you want to check the type of objects coming from different window objects, say that of an iframe or a popup window. This is because there's a different version of each core type constructor in each `window', i.e.
iframe.contentWindow.Array === Array // false
Using the instanceof operator...
The instanceof operator is a clean way of testing object type as well, but has its own potential issues, just like the constructor property.
var myArray = [1,2,3];
(myArray instanceof Array); // true
(myArray instanceof Object); // true
But instanceof fails to work for literal values (because literals are not Objects)
3 instanceof Number // false
'abc' instanceof String // false
true instanceof Boolean // false
The literals need to be wrapped in an Object in order for instanceof to work, for example
new Number(3) instanceof Number // true
The .constructor check works fine for literals because the . method invocation implicitly wraps the literals in their respective object type
3..constructor === Number // true
'abc'.constructor === String // true
true.constructor === Boolean // true
Why two dots for the 3? Because Javascript interprets the first dot as a decimal point ;)
Will not work cross-frame and cross-window
instanceof also will not work across different windows, for the same reason as the constructor property check.
Using the name property of the constructor property...
Does not work AT ALL in many cases
Again, see above; it's quite common for constructor to be utterly and completely wrong and useless.
Does NOT work in <IE9
Using myObjectInstance.constructor.name will give you a string containing the name of the constructor function used, but is subject to the caveats about the constructor property that were mentioned earlier.
For IE9 and above, you can monkey-patch in support:
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s+([^\s(]+)\s*\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1] : "";
},
set: function(value) {}
});
}
Updated version from the article in question. This was added 3 months after the article was published, this is the recommended version to use by the article's author Matthew Scharley. This change was inspired by comments pointing out potential pitfalls in the previous code.
if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
Object.defineProperty(Function.prototype, 'name', {
get: function() {
var funcNameRegex = /function\s([^(]{1,})\(/;
var results = (funcNameRegex).exec((this).toString());
return (results && results.length > 1) ? results[1].trim() : "";
},
set: function(value) {}
});
}
Using Object.prototype.toString
It turns out, as this post details, you can use Object.prototype.toString - the low level and generic implementation of toString - to get the type for all built-in types
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
One could write a short helper function such as
function type(obj){
return Object.prototype.toString.call(obj).slice(8, -1);
}
to remove the cruft and get at just the type name
type('abc') // String
However, it will return Object for all user-defined types.
Caveats for all...
All of these are subject to one potential problem, and that is the question of how the object in question was constructed. Here are various ways of building objects and the values that the different methods of type checking will return:
// using a named function:
function Foo() { this.a = 1; }
var obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == "Foo"); // true
// let's add some prototypical inheritance
function Bar() { this.b = 2; }
Foo.prototype = new Bar();
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // false
(obj.constructor.name == "Foo"); // false
// using an anonymous function:
obj = new (function() { this.a = 1; })();
(obj instanceof Object); // true
(obj.constructor == obj.constructor); // true
(obj.constructor.name == ""); // true
// using an anonymous function assigned to a variable
var Foo = function() { this.a = 1; };
obj = new Foo();
(obj instanceof Object); // true
(obj instanceof Foo); // true
(obj.constructor == Foo); // true
(obj.constructor.name == ""); // true
// using object literal syntax
obj = { foo : 1 };
(obj instanceof Object); // true
(obj.constructor == Object); // true
(obj.constructor.name == "Object"); // true
While not all permutations are present in this set of examples, hopefully there are enough to provide you with an idea about how messy things might get depending on your needs. Don't assume anything, if you don't understand exactly what you are after, you may end up with code breaking where you don't expect it to because of a lack of grokking the subtleties.
NOTE:
Discussion of the typeof operator may appear to be a glaring omission, but it really isn't useful in helping to identify whether an object is a given type, since it is very simplistic. Understanding where typeof is useful is important, but I don't currently feel that it is terribly relevant to this discussion. My mind is open to change though. :)
Jason Bunting's answer gave me enough of a clue to find what I needed:
<<Object instance>>.constructor.name
So, for example, in the following piece of code:
function MyObject() {}
var myInstance = new MyObject();
myInstance.constructor.name would return "MyObject".
A little trick I use:
function Square(){
this.className = "Square";
this.corners = 4;
}
var MySquare = new Square();
console.log(MySquare.className); // "Square"
Update
To be precise, I think OP asked for a function that retrieves the constructor name for a particular object. In terms of Javascript, object does not have a type but is a type of and in itself. However, different objects can have different constructors.
Object.prototype.getConstructorName = function () {
var str = (this.prototype ? this.prototype.constructor : this.constructor).toString();
var cname = str.match(/function\s(\w*)/)[1];
var aliases = ["", "anonymous", "Anonymous"];
return aliases.indexOf(cname) > -1 ? "Function" : cname;
}
new Array().getConstructorName(); // returns "Array"
(function () {})().getConstructorName(); // returns "Function"
 
Note: the below example is deprecated.
A blog post linked by Christian Sciberras contains a good example on how to do it. Namely, by extending the Object prototype:
if (!Object.prototype.getClassName) {
Object.prototype.getClassName = function () {
return Object.prototype.toString.call(this).match(/^\[object\s(.*)\]$/)[1];
}
}
var test = [1,2,3,4,5];
alert(test.getClassName()); // returns Array
Using Object.prototype.toString
It turns out, as this post details, you can use Object.prototype.toString - the low level and generic implementation of toString - to get the type for all built-in types
Object.prototype.toString.call('abc') // [object String]
Object.prototype.toString.call(/abc/) // [object RegExp]
Object.prototype.toString.call([1,2,3]) // [object Array]
One could write a short helper function such as
function type(obj){
return Object.prototype.toString.call(obj]).match(/\s\w+/)[0].trim()
}
return [object String] as String
return [object Number] as Number
return [object Object] as Object
return [object Undefined] as Undefined
return [object Function] as Function
You should use somevar.constructor.name like a:
const getVariableType = a => a.constructor.name.toLowerCase();
const d = new Date();
const res1 = getVariableType(d); // 'date'
const num = 5;
const res2 = getVariableType(num); // 'number'
const fn = () => {};
const res3 = getVariableType(fn); // 'function'
console.log(res1); // 'date'
console.log(res2); // 'number'
console.log(res3); // 'function'
Here is a solution that I have come up with that solves the shortcomings of instanceof. It can check an object's types from cross-windows and cross-frames and doesn't have problems with primitive types.
function getType(o) {
return Object.prototype.toString.call(o).match(/^\[object\s(.*)\]$/)[1];
}
function isInstance(obj, type) {
var ret = false,
isTypeAString = getType(type) == "String",
functionConstructor, i, l, typeArray, context;
if (!isTypeAString && getType(type) != "Function") {
throw new TypeError("type argument must be a string or function");
}
if (obj !== undefined && obj !== null && obj.constructor) {
//get the Function constructor
functionConstructor = obj.constructor;
while (functionConstructor != functionConstructor.constructor) {
functionConstructor = functionConstructor.constructor;
}
//get the object's window
context = functionConstructor == Function ? self : functionConstructor("return window")();
//get the constructor for the type
if (isTypeAString) {
//type is a string so we'll build the context (window.Array or window.some.Type)
for (typeArray = type.split("."), i = 0, l = typeArray.length; i < l && context; i++) {
context = context[typeArray[i]];
}
} else {
//type is a function so execute the function passing in the object's window
//the return should be a constructor
context = type(context);
}
//check if the object is an instance of the constructor
if (context) {
ret = obj instanceof context;
if (!ret && (type == "Number" || type == "String" || type == "Boolean")) {
ret = obj.constructor == context
}
}
}
return ret;
}
isInstance requires two parameters: an object and a type. The real trick to how it works is that it checks if the object is from the same window and if not gets the object's window.
Examples:
isInstance([], "Array"); //true
isInstance("some string", "String"); //true
isInstance(new Object(), "Object"); //true
function Animal() {}
function Dog() {}
Dog.prototype = new Animal();
isInstance(new Dog(), "Dog"); //true
isInstance(new Dog(), "Animal"); //true
isInstance(new Dog(), "Object"); //true
isInstance(new Animal(), "Dog"); //false
The type argument can also be a callback function which returns a constructor. The callback function will receive one parameter which is the window of the provided object.
Examples:
//"Arguments" type check
var args = (function() {
return arguments;
}());
isInstance(args, function(w) {
return w.Function("return arguments.constructor")();
}); //true
//"NodeList" type check
var nl = document.getElementsByTagName("*");
isInstance(nl, function(w) {
return w.document.getElementsByTagName("bs").constructor;
}); //true
One thing to keep in mind is that IE < 9 does not provide the constructor on all objects so the above test for NodeList would return false and also a isInstance(alert, "Function") would return false.
I was actually looking for a similar thing and came across this question. Here is how I get types: jsfiddle
var TypeOf = function ( thing ) {
var typeOfThing = typeof thing;
if ( 'object' === typeOfThing ) {
typeOfThing = Object.prototype.toString.call( thing );
if ( '[object Object]' === typeOfThing ) {
if ( thing.constructor.name ) {
return thing.constructor.name;
}
else if ( '[' === thing.constructor.toString().charAt(0) ) {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
else {
typeOfThing = thing.constructor.toString().match( /function\s*(\w+)/ );
if ( typeOfThing ) {
return typeOfThing[1];
}
else {
return 'Function';
}
}
}
else {
typeOfThing = typeOfThing.substring( 8,typeOfThing.length - 1 );
}
}
return typeOfThing.charAt(0).toUpperCase() + typeOfThing.slice(1);
}
Use constructor.name when you can, and regex function when I can't.
Function.prototype.getName = function(){
if (typeof this.name != 'undefined')
return this.name;
else
return /function (.+)\(/.exec(this.toString())[1];
};
The kind() function from Agave.JS will return:
the closest prototype in the inheritance tree
for always-primitive types like 'null' and 'undefined', the primitive name.
It works on all JS objects and primitives, regardless of how they were created, and doesn't have any surprises.
var kind = function(item) {
var getPrototype = function(item) {
return Object.prototype.toString.call(item).slice(8, -1);
};
var kind, Undefined;
if (item === null ) {
kind = 'null';
} else {
if ( item === Undefined ) {
kind = 'undefined';
} else {
var prototype = getPrototype(item);
if ( ( prototype === 'Number' ) && isNaN(item) ) {
kind = 'NaN';
} else {
kind = prototype;
}
}
}
return kind;
};
Examples:
Numbers
kind(37) === 'Number'
kind(3.14) === 'Number'
kind(Math.LN2) === 'Number'
kind(Infinity) === 'Number'
kind(Number(1)) === 'Number'
kind(new Number(1)) === 'Number'
NaN
kind(NaN) === 'NaN'
Strings
kind('') === 'String'
kind('bla') === 'String'
kind(String("abc")) === 'String'
kind(new String("abc")) === 'String'
Booleans
kind(true) === 'Boolean'
kind(false) === 'Boolean'
kind(new Boolean(true)) === 'Boolean'
Arrays
kind([1, 2, 4]) === 'Array'
kind(new Array(1, 2, 3)) === 'Array'
Objects
kind({a:1}) === 'Object'
kind(new Object()) === 'Object'
Dates
kind(new Date()) === 'Date'
Functions
kind(function(){}) === 'Function'
kind(new Function("console.log(arguments)")) === 'Function'
kind(Math.sin) === 'Function'
undefined
kind(undefined) === 'undefined'
null
kind(null) === 'null'
Here is an implementation based on the accepted answer:
/**
* Describes the type of a variable.
*/
class VariableType
{
type;
name;
/**
* Creates a new VariableType.
*
* #param {"undefined" | "null" | "boolean" | "number" | "bigint" | "array" | "string" | "symbol" |
* "function" | "class" | "object"} type the name of the type
* #param {null | string} [name = null] the name of the type (the function or class name)
* #throws {RangeError} if neither <code>type</code> or <code>name</code> are set. If <code>type</code>
* does not have a name (e.g. "number" or "array") but <code>name</code> is set.
*/
constructor(type, name = null)
{
switch (type)
{
case "undefined":
case "null":
case "boolean" :
case "number" :
case "bigint":
case "array":
case "string":
case "symbol":
if (name !== null)
throw new RangeError(type + " may not have a name");
}
this.type = type;
this.name = name;
}
/**
* #return {string} the string representation of this object
*/
toString()
{
let result;
switch (this.type)
{
case "function":
case "class":
{
result = "a ";
break;
}
case "object":
{
result = "an ";
break;
}
default:
return this.type;
}
result += this.type;
if (this.name !== null)
result += " named " + this.name;
return result;
}
}
const functionNamePattern = /^function\s+([^(]+)?\(/;
const classNamePattern = /^class(\s+[^{]+)?{/;
/**
* Returns the type information of a value.
*
* <ul>
* <li>If the input is undefined, returns <code>(type="undefined", name=null)</code>.</li>
* <li>If the input is null, returns <code>(type="null", name=null)</code>.</li>
* <li>If the input is a primitive boolean, returns <code>(type="boolean", name=null)</code>.</li>
* <li>If the input is a primitive number, returns <code>(type="number", name=null)</code>.</li>
* <li>If the input is a primitive or wrapper bigint, returns
* <code>(type="bigint", name=null)</code>.</li>
* <li>If the input is an array, returns <code>(type="array", name=null)</code>.</li>
* <li>If the input is a primitive string, returns <code>(type="string", name=null)</code>.</li>
* <li>If the input is a primitive symbol, returns <code>(type="symbol", null)</code>.</li>
* <li>If the input is a function, returns <code>(type="function", name=the function name)</code>. If the
* input is an arrow or anonymous function, its name is <code>null</code>.</li>
* <li>If the input is a function, returns <code>(type="function", name=the function name)</code>.</li>
* <li>If the input is a class, returns <code>(type="class", name=the name of the class)</code>.
* <li>If the input is an object, returns
* <code>(type="object", name=the name of the object's class)</code>.
* </li>
* </ul>
*
* Please note that built-in types (such as <code>Object</code>, <code>String</code> or <code>Number</code>)
* may return type <code>function</code> instead of <code>class</code>.
*
* #param {object} value a value
* #return {VariableType} <code>value</code>'s type
* #see http://stackoverflow.com/a/332429/14731
* #see isPrimitive
*/
function getTypeInfo(value)
{
if (value === null)
return new VariableType("null");
const typeOfValue = typeof (value);
const isPrimitive = typeOfValue !== "function" && typeOfValue !== "object";
if (isPrimitive)
return new VariableType(typeOfValue);
const objectToString = Object.prototype.toString.call(value).slice(8, -1);
// eslint-disable-next-line #typescript-eslint/ban-types
const valueToString = value.toString();
if (objectToString === "Function")
{
// A function or a constructor
const indexOfArrow = valueToString.indexOf("=>");
const indexOfBody = valueToString.indexOf("{");
if (indexOfArrow !== -1 && (indexOfBody === -1 || indexOfArrow < indexOfBody))
{
// Arrow function
return new VariableType("function");
}
// Anonymous and named functions
const functionName = functionNamePattern.exec(valueToString);
if (functionName !== null && typeof (functionName[1]) !== "undefined")
{
// Found a named function or class constructor
return new VariableType("function", functionName[1].trim());
}
const className = classNamePattern.exec(valueToString);
if (className !== null && typeof (className[1]) !== "undefined")
{
// When running under ES6+
return new VariableType("class", className[1].trim());
}
// Anonymous function
return new VariableType("function");
}
if (objectToString === "Array")
return new VariableType("array");
const classInfo = getTypeInfo(value.constructor);
return new VariableType("object", classInfo.name);
}
function UserFunction()
{
}
function UserClass()
{
}
let anonymousFunction = function()
{
};
let arrowFunction = i => i + 1;
console.log("getTypeInfo(undefined): " + getTypeInfo(undefined));
console.log("getTypeInfo(null): " + getTypeInfo(null));
console.log("getTypeInfo(true): " + getTypeInfo(true));
console.log("getTypeInfo(5): " + getTypeInfo(5));
console.log("getTypeInfo(\"text\"): " + getTypeInfo("text"));
console.log("getTypeInfo(userFunction): " + getTypeInfo(UserFunction));
console.log("getTypeInfo(anonymousFunction): " + getTypeInfo(anonymousFunction));
console.log("getTypeInfo(arrowFunction): " + getTypeInfo(arrowFunction));
console.log("getTypeInfo(userObject): " + getTypeInfo(new UserClass()));
console.log("getTypeInfo(nativeObject): " + getTypeInfo(navigator.mediaDevices.getUserMedia));
We only use the constructor property when we have no other choice.
You can use the instanceof operator to see if an object is an instance of another, but since there are no classes, you can't get a class name.
You can use the "instanceof" operator to determine if an object is an instance of a certain class or not. If you do not know the name of an object's type, you can use its constructor property. The constructor property of objects, is a reference to the function that is used to initialize them. Example:
function Circle (x,y,radius) {
this._x = x;
this._y = y;
this._radius = raduius;
}
var c1 = new Circle(10,20,5);
Now c1.constructor is a reference to the Circle() function.
You can alsow use the typeof operator, but the typeof operator shows limited information. One solution is to use the toString() method of the Object global object. For example if you have an object, say myObject, you can use the toString() method of the global Object to determine the type of the class of myObject. Use this:
Object.prototype.toString.apply(myObject);
Say you have var obj;
If you just want the name of obj's type, like "Object", "Array", or "String",
you can use this:
Object.prototype.toString.call(obj).split(' ')[1].replace(']', '');
The closest you can get is typeof, but it only returns "object" for any sort of custom type. For those, see Jason Bunting.
Edit, Jason's deleted his post for some reason, so just use Object's constructor property.
For of those of you reading this and want a simple solution that works fairly well and has been tested:
const getTypeName = (thing) => {
const name = typeof thing
if (name !== 'object') return name
if (thing instanceof Error) return 'error'
if (!thing) return 'null'
return ({}).toString.call(thing).match(/\s([a-zA-Z]+)/)[1].toLowerCase()
}
To get insight on why this works, checkout the polyfill documentation for Array.isArray(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray#polyfill
If anyone was looking for a solution which is working with jQuery, here is the adjusted wiki code (the original breaks jQuery).
Object.defineProperty(Object.prototype, "getClassName", {
value: function() {
var funcNameRegex = /function (.{1,})\(/;
var results = (funcNameRegex).exec((this).constructor.toString());
return (results && results.length > 1) ? results[1] : "";
}
});
Lodash has many isMethods so if you're using Lodash maybe a mixin like this can be useful:
// Mixin for identifying a Javascript Object
_.mixin({
'identify' : function(object) {
var output;
var isMethods = ['isArguments', 'isArray', 'isArguments', 'isBoolean', 'isDate', 'isArguments',
'isElement', 'isError', 'isFunction', 'isNaN', 'isNull', 'isNumber',
'isPlainObject', 'isRegExp', 'isString', 'isTypedArray', 'isUndefined', 'isEmpty', 'isObject']
this.each(isMethods, function (method) {
if (this[method](object)) {
output = method;
return false;
}
}.bind(this));
return output;
}
});
It adds a method to lodash called "identify" which works as follow:
console.log(_.identify('hello friend')); // isString
Plunker:
http://plnkr.co/edit/Zdr0KDtQt76Ul3KTEDSN
Ok, folks I've been slowly building a catch all method for this over some years lol! The trick is to:
Have a mechanism for creating classes.
Have a mechanism for checking all user created classes, primitives and values created/generated by native constructors.
Have a mechanism for extending user created classes into new ones so that the above functionality permeates through your code/application/library/etc..
For an example (or to see how I dealt with the problem) look at the following code on github: https://github.com/elycruz/sjljs/blob/master/src/sjl/sjl.js and search for:
classOf =,
classOfIs =, and or
defineSubClass = (without the backticks (`)).
As you can see I have some mechanisms in place to force classOf to always give me the classes/constructors type name regardless of whether it is a primitive, a user defined class, a value created using a native constructor, Null, NaN, etc.. For every single javascript value I will get it's unique type name from the classOf function. In addition I can pass in actual constructors into sjl.classOfIs to check a value's type in addition to being able to pass in it's type name as well! So for example:
```
// Please forgive long namespaces! I had no idea on the impact until after using them for a while (they suck haha)
var SomeCustomClass = sjl.package.stdlib.Extendable.extend({
constructor: function SomeCustomClass () {},
// ...
}),
HelloIterator = sjl.ns.stdlib.Iterator.extend(
function HelloIterator () {},
{ /* ... methods here ... */ },
{ /* ... static props/methods here ... */ }
),
helloIt = new HelloIterator();
sjl.classOfIs(new SomeCustomClass(), SomeCustomClass) === true; // `true`
sjl.classOfIs(helloIt, HelloIterator) === true; // `true`
var someString = 'helloworld';
sjl.classOfIs(someString, String) === true; // `true`
sjl.classOfIs(99, Number) === true; // true
sjl.classOf(NaN) === 'NaN'; // true
sjl.classOf(new Map()) === 'Map';
sjl.classOf(new Set()) === 'Set';
sjl.classOfIs([1, 2, 4], Array) === true; // `true`
// etc..
// Also optionally the type you want to check against could be the type's name
sjl.classOfIs(['a', 'b', 'c'], 'Array') === true; // `true`!
sjl.classOfIs(helloIt, 'HelloIterator') === true; // `true`!
```
If you are interested in reading more on how I use the setup mentioned above take a look at the repo: https://github.com/elycruz/sjljs
Also books with content on the subject:
- "JavaScript Patterns" by Stoyan Stefanov.
- "Javascript - The Definitive Guide." by David Flanagan.
- and many others.. (search le` web).
Also you can quickly test the features I'm talking about here:
- http://sjljs.elycruz.com/0.5.18/tests/for-browser/ (also the 0.5.18 path in the url has the sources from github on there minus the node_modules and such).
Happy Coding!
Fairly Simple!
My favorite method to get type of anything in JS
function getType(entity){
var x = Object.prototype.toString.call(entity)
return x.split(" ")[1].split(']')[0].toLowerCase()
}
my favorite method to check type of anything in JS
function checkType(entity, type){
return getType(entity) === type
}
Use class.name. This also works with function.name.
class TestA {}
console.log(TestA.name); // "TestA"
function TestB() {}
console.log(TestB.name); // "TestB"

Categories

Resources