How to check the class of an instance in Javascript? [duplicate]
You probably mean type or constructor, not class. Class has a different meaning in JavaScript.
var getClassOf = Function.prototype.call.bind(Object.prototype.toString); getClassOf(new Date()); // => "[object Date]" getClassOf('test string'); // => "[object String]" getClassOf(< x: 1 >); // => "[object Object]" getClassOf(function() < >); // => "[object Function]"
To get the constructor or prototype there are several ways, depending on what you need.
To discover what type of primitive you have, use typeof . This is the best thing to use with strings, booleans, numbers, etc:
typeof 'test string'; // => 'string' typeof 3; // => 'number' typeof false; // => 'boolean' typeof function() < >; // => 'function' typeof < x: 1 >; // => 'object' typeof undefined; // => 'undefined'
Just beware that null acts weird in this case, as typeof null will give you «object» , not «null» .
You can also get the prototype, the backbone JavaScript inheritance, with Object.getPrototypeOf(myObject) (or myObject.__proto__ or myObject.constructor.prototype in some browsers when getPrototypeOf isn’t supported).
You can test the constructor with instanceof :
new Date() instanceof Date; // => true
You can also reasonably get the constructor with myObject.constructor , although be aware that this can be changed. To get the name of the constructor, use myObject.constructor.name .
new Date().constructor.name; // => 'Date'
Function.prototype.call.bind(Object.prototype.toString) won’t work for instances of custom constructors: getClassOf(new function CC()<>()) returns [object Object]
@KooiInc It works; it returns the class , which is Object. If you want the constructor you use instanceof or constructor.name . It’s not a matter of whether it works. It’s a matter of whether you understand what a class is in JavaScript (see my note at the beginning of the post, «You probably mean type or constructor, not class»).
@wnwall—neither instanceOf or the constructor property are reliable, and certainly not for host objects (like DOM objects). Not all javascript objects inherit from or are instances of Object (e.g. certain host objets in some browsers). If, in javascript, you find you need to discover what «class» an object is, you’re probably going about things the wrong way.
I’m not arguing that class information should be used in most situations, as I said, the OP was probably looking for constructor information. But class information can be helpful and it’s good to know about for completeness. JavaScript itself is implemented using [[Class]] information. The ES3 specification for Date.prototype.getTime says it should check arguments based on [[Class]]. They use class, not constructor/proto, information. It can be helpful also in cross-frame objects. Why would you want to argue about expanding better knowledge and understanding of the intricacies of JavaScript?
Not sure if this goes for all browsers, but you can use constructor.name :
'some string'.constructor.name; //=>String (<>).constructor.name //=>Object (7.3).constructor.name //=>Number [].constructor.name //=>Array (function()<>).constructor.name //=>Function true.constructor.name //=>Boolean /test/i.constructor.name //=>RegExp (new Date).constructor.name //=>Date (new function MyConstructor()<>()) .constructor.name; //=>MyConstructor
Whilst Object is the mother of all in Javascript, you could extend it (there are pros and cons to it)
Object.prototype.class = function() < return this.constructor.name; >'some string'.class(); //=>String (23).class(); //=>Number // etc.
Note: javascript doesn’t know ‘classes’ 1 , its inheritance model is prototypal
1 from the ECMAScript standard.
ECMAScript does not use classes such as those in C++, Smalltalk, or Java. Instead objects may be created in various ways including via a literal notation or via constructors which create objects and then execute code that initialises all or part of them by assigning initial values to their properties. Each constructor is a function that has a property named prototype that is used to implement prototype-based inheritance and shared properties. Objects are created by using constructors in new expressions; for example, new Date(2009,11) creates a new Date object. Invoking a constructor without using new has consequences that depend on the constructor. For example, Date() produces a string representation of the current date and time rather than an object.
Can I find the class name of a argument of the a function in javascript?
Problem description:
suppose I do not know what is req/req.url and I want to find something more about it. I know definitely there is class which has a member called url. And maybe req is instance of that class, maybe req is instance of a class inherit that class. Question:
Can I find the class name of req? Because req is of some class and inherit more classes. You have to define url member in some class.
Second part
Problem description:
Is there someway in javascript I could find that class, so I could go ahead to see the code or documentation? for example,
var http1 = require('http'); func(http1), //is there a function? I could get "http".
Third part
var server = http.createServer(function(req, res) < . >http.createServer([requreListerner]) returns a new web server object.
request is an instance of http.IncomingMessage and response is an instance of http.ServerResponse. Code:
var server = http.createServer(function(req, res) < func(req) // is there a function? return http.IncomingMessage func(res) // is there a function? return http.ServerResponse . >);
Question:
is there a function? return http.IncomingMessage is there a function? return http.ServerResponse
req.constructor.name might give you the info you need.but its not always a safe bet to use, because you can overwrite them
3 Answers 3
There are a few separate issues here.
What is a class?
JavaScript has an instanceof operator, and certain runtime values make sense to use on the right of instanceof , so arguably, JavaScript has classes.
Type names
JavaScript does not have a nominal type system, so even though there might be classes, there is no such thing as a class name built into the language.
You could define a name as a dotted path of property names from the global object so that x != null && (typeof x == ‘object’) && (x instanceof eval(typeName(x)) is true. There are a number of problems with that though discussed below.
Name stability
For a name to be useful, it needs to address something. JavaScript does not attempt to guarantee name stability, and JavaScript programs often violate it.
For name stability to hold, you’d need
var localMyType = MyType; . // Program here eval("MyType") === MyType // Still true
unless the program does something really odd.
That’s simply not the case.
There is no guarantee that any path of property lookups from the global object will arrive at the same constructor. JavaScript programs often violate this.
Name completeness
It’s not uncommon for constuctors to be unreachable from the global object.
(function () < var instance; function Typ() <>(function () < var Typ = function () <>; Typ.prototype.x = 1; instance = new Typ; alert(instance instanceof Typ); // true >)(); alert(instance instanceof Typ); // false >();
The type of instance is not reachable by any path of property lookups from the global objects, so any naming scheme layered on JS would not be complete.
The practice of wrapping modules in a closure envelope and then assigning the public interface to a global variables makes any types used as implementation details unnameable.
The term class is used very loosely in Javascript, as they are not really classes but objects passed to functions with contexts (that can be overridden).
@Qix, yep. That’s why I defined it as a value appropriate on the right of instanceof instead of trying to get super-specific.
@Mike’s answer is correct. Here’s some code
// make a function (any function in JavaScript is a constructor) function A() <> // Make an instance of A x = new A(); // print x's 'class' console.log(x.constructor.name); // prints "A" // make another function var B = function() <>; // make an instance of B y = new B(); // print y's 'class' y.constructor.name // prints ""
So as you can see depending on how the class was made there’s no guarantee you can find any name as their may be no name. You can use instanceof though it see if an object is one thing or another
console.log(x instanceof A); // prints "true" console.log(y instanceof A); // prints "false console.log(x instanceof B); // prints "false console.log(y instanceof B); // prints "true
As @Mike points out, instanceof only works if you have a reference to the function that was passed to new which you often don’t
Unfortunately, this part of your assumption:
Because req is of some class and inherit more classes. You have to define url member in some class.
is incorrect. Javascript doesn’t have classes and there is no reason that req and res need to be classes to have members. req.constructor === Object && res.constructor === Object is perfectly legitimate. For example:
In the above example, both req and res are instances of Object , but they don’t inherit from other classes. This is quite common in JS. Even if they do have their internal [[Prototype]] property set to point to another object there is no guarantee that that object is a «class»:
var requestProto = < url: getUrlFromEnv() >; var req = Object.create(requestProto);
Your best bet is Object.getPrototypeOf which will do the right thing in cases of inheritance, but will not help you in cases where new anonymous objects are being constructed that conform to a certain shape. (In such cases your only recourse is to read the source code where those objects are defined and everywhere in the call stack that has access to those objects since all objects are mutable by default).
javascript get type/instance name
Is there a reliable way of getting the instance of a JavaScript object? For example, relying on the fake ‘ obj.getInstance() ‘ function.
var T = < Q: < W: < C: function() <>> > >; var x = new T.Q.W.C(); console.log( x.getInstance() === T.Q.W.C); // should output true
If this is not part of the ECMA specification, please include browser/node.js support and compatibility in answers.
I think you have to rephrase the question. x is an instance and yes, using new is pretty reliable to get an instance. Maybe you are looking for instancof , to get the type of the instance? developer.mozilla.org/en/JavaScript/Reference/Operators/Special/…
TL;DR: In regards to the actual question in the title («get type/instance name»), use Object.getPrototypeOf(instanceName).constructor to safely access (due to immutability) the object’s constructor function, which will be its actual JS type (e.g. the type of its class , or just Object , Function , Number , String , etc.), and then use theType.name to get the string name of said type. For unsafe access, you could simply use instanceName.constructor .
As for the question itself, the example code is sort of poorly framed (though this is not a criticism as obviously one can’t be expected to know how to perfectly ask something they’re learning about). I think the best you’re gonna be able to do with that code is just check for things using instanceof like the other comments/answers describe. More likely one would be using class es with extends for inheritance.
In that case, use the method I just provided; or, if you want the base class type, you can put a function inside the class (can’t be set on the .prototype ) and then use super.constructor instead. Note that here you can’t use Object.getPrototypeOf(super) , because super is just a JS keyword. You could then for instance return the type from the function. It seems that you can only ever access 1 super , the immediate parent, though. Another approach would be to store this.constructor or super.constructor as a property of each class .
6 Answers 6
function FooBar() < >var foobar = new FooBar(); console.log(foobar.constructor.name); // Prints 'FooBar'
To get a pointer to the instantiating function (which is not a «class», but is the type), use obj.constructor where obj is any object.
In JavaScript there are no classes. As such, there are no class instances in JavaScript. There are only objects. Objects inherit from other objects (their so called prototypes). What you are doing in your code is literally defining an object T, which’s attribute Q is another object, which’s attribute W is another object, which’s attribute C is a function.
When you are «creating a new instance of T.Q.W.C», you are actually only calling the function T.Q.W.C as a constructor. A function called as a constructor will return a new object on which the constructor function was called (that is with this beeing the new object, like constructorFunction.apply(newObject, arguments); ). That returned object will have a hidden property constructor which will point to the function that was invoked as a constrcutor to create the object. Additionally there is a language feature which allows you to test if a given function was used as the constructor function for an object using the instanceof operator.
So you could do the following:
console.log(x instanceof T.Q.W.C);
console.log(x.constructor === T.Q.W.C);