30

Possible Duplicate:
How to get a JavaScript Object's Class?

In Ruby I could do this to check the class of an instance:

'this is an string'.class

=>String

Is there any similar thing in js?

Community
  • 1
  • 1
mko
  • 21,334
  • 49
  • 130
  • 191

4 Answers4

48

You probably mean type or constructor, not class. Class has a different meaning in JavaScript.

To get the class:

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]"

See this related MDN article.

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'
Nathan Wall
  • 6,426
  • 2
  • 22
  • 23
  • `Function.prototype.call.bind(Object.prototype.toString);` - this is really nice. +1 – Nemoden Aug 18 '12 at 13:31
  • `Function.prototype.call.bind(Object.prototype.toString)` won't work for instances of custom constructors: `getClassOf(new function CC(){}())` returns `[object Object]` – KooiInc Aug 18 '12 at 13:44
  • @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"). – Nathan Wall Aug 18 '12 at 13:48
  • @wnwall: the constructor of `new function CC(){}()` is `CC`, and ofcourse `Object` in the end, but that's not very informative. I think I do understand 'class' in Javascript. As in: you can simulate it, but there's no need to do that. See the link at the bottom of my answer. – KooiInc Aug 18 '12 at 14:00
  • @KooiInc: `[[Class]]` has a very technical meaning in JavaScript that describes a very limited number of "classes" an object could be in: Function, Array, Boolean, Number, RegExp, etc. If the object is an instance of a custom constructor, it is in the Object class. See http://perfectionkills.com/category/class/ . Specifically search for `[[Class]]` or `Object.prototype.toString`. Also see the MDN article I cited in my original post. – Nathan Wall Aug 18 '12 at 14:03
  • Knowing the class can be important in some situations, like implementing the [HTML5 internal structured cloning algorithm](http://www.w3.org/TR/html5/common-dom-interfaces.html#safe-passing-of-structured-data) – Nathan Wall Aug 18 '12 at 14:08
  • 1
    @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. – RobG Aug 18 '12 at 14:15
  • 1
    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? – Nathan Wall Aug 18 '12 at 17:16
19

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.

guijob
  • 4,413
  • 3
  • 20
  • 39
KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • 1
    +1 for pointing out the different meaning of `Object` in js, and good reference for prototype – mko Aug 18 '12 at 13:33
  • Please note, you should not use constructor.name in React apps. When production bundle is build, the classes will be minimized, and will not match. I already faced this problem twice :) in two different projects – Kostanos Jul 24 '22 at 14:56
3

typeof and instanceof is what you need

> x = "Hello, World!"
"Hello, World!"
> typeof x
"string"

You can check constructors name to get a name of constructors class (or that what you call a class):

> x.constructor.name
> "String"
sandstrom
  • 14,554
  • 7
  • 65
  • 62
Nemoden
  • 8,816
  • 6
  • 41
  • 65
  • That should only return `object` though, should it not? That won't tell you the name of the class (though not sure OP needs that). – Brad Christie Aug 18 '12 at 13:02
  • Does it also apply to DOM object? element = document.getElementById('foo'); typeof element; it return 'object', this is the parent class not `document.element` – mko Aug 18 '12 at 13:03
  • @BradChristie Yes, that's what I just find out? Do you have better solution? – mko Aug 18 '12 at 13:04
  • Brad, if a variable's type is primitive such as undefined, null, boolean, string and number `typeof` will return it. E.g. if `y` is not defined: `typeof y` -> "undefined". But I agree, `typeof` is not what the OP need, so, I updated my answer. – Nemoden Aug 18 '12 at 13:09
  • @yozloy: Nope. JavaScript doesn't have "classes". It has objects and functions which, when paired or used certain ways, can mimic classes. But I think the best you're going to get is if it's an object. – Brad Christie Aug 18 '12 at 13:10
  • @Nemoden: I'm aware, but the original question was left ambiguous; I wasn't certain if just knowing it's an object was enough or if OP wanted the name it came from. e.g. `var foo = new Bar();` then determine `someMagic(foo)` results in discovering it's an instance of `Bar`. – Brad Christie Aug 18 '12 at 13:11
  • @Nemoden sorry x.constructor.name doesn't work for DOM element class, it return `undefined` but constructor method does return `HTMLSpanElementConstructor` which ok for indication, but still not perfect class name – mko Aug 18 '12 at 13:13
  • @Nemoden `x.constructor` holds a function reference. `x.constructor.name` only works when the function reference = constructor function is a named function. – Rob W Aug 18 '12 at 13:17
  • Well, if you want to check if an element is a HTML Element, you just go with `x instanceof HTMLElement` and to identify the exact class name you go with `x.constructor.name` (but you said it does not work which is really odd). – Nemoden Aug 18 '12 at 13:20
  • @Rob, Isn't a constructor function always a named function? – Nemoden Aug 18 '12 at 13:29
  • 1
    @Nemoden `var MyConstructor = function(){};var instance = new MyConstructor;console.log(instance.constructor.name);/*""*/` – Rob W Aug 18 '12 at 13:48
  • @Rob, oops, now it seems to be obvoius :-) thanks! – Nemoden Aug 19 '12 at 10:31
3

In js you can use :

typeof

eq.

var a="this is string";
typeof a; // return "string"

function abc(){}
typeof abc; // return "function"

var a = {a:1,b:2,c:3}
typeof a; return "object"
amd
  • 20,637
  • 6
  • 49
  • 67
  • +1 while not perfect, `typeof` is more reliable than all the other suggested methods. – RobG Aug 18 '12 at 14:18