Get name of object or class
Get your object's constructor function and then inspect its name property.
myObj.constructor.name
Returns "myClass".
How to get class object's name as a string in Javascript?
Shog9 is right that this doesn't make all that much sense to ask, since an object could be referred to by multiple variables. If you don't really care about that, and all you want is to find the name of one of the global variables that refers to that object, you could do the following hack:
function myClass() {
this.myName = function () {
// search through the global object for a name that resolves to this object
for (var name in this.global)
if (this.global[name] == this)
return name
}
}
// store the global object, which can be referred to as this at the top level, in a
// property on our prototype, so we can refer to it in our object's methods
myClass.prototype.global = this
// create a global variable referring to an object
var myVar = new myClass()
myVar.myName() // returns "myVar"
Note that this is an ugly hack, and should not be used in production code. If there is more than one variable referring to an object, you can't tell which one you'll get. It will only search the global variables, so it won't work if a variable is local to a function. In general, if you need to name something, you should pass the name in to the constructor when you create it.
edit: To respond to your clarification, if you need to be able to refer to something from an event handler, you shouldn't be referring to it by name, but instead add a function that refers to the object directly. Here's a quick example that I whipped up that shows something similar, I think, to what you're trying to do:
function myConstructor () {
this.count = 0
this.clickme = function () {
this.count += 1
alert(this.count)
}
var newDiv = document.createElement("div")
var contents = document.createTextNode("Click me!")
// This is the crucial part. We don't construct an onclick handler by creating a
// string, but instead we pass in a function that does what we want. In order to
// refer to the object, we can't use this directly (since that will refer to the
// div when running event handler), but we create an anonymous function with an
// argument and pass this in as that argument.
newDiv.onclick = (function (obj) {
return function () {
obj.clickme()
}
})(this)
newDiv.appendChild(contents)
document.getElementById("frobnozzle").appendChild(newDiv)
}
window.onload = function () {
var myVar = new myConstructor()
}
How can i get a object's name into string form using JS?
You can't access the name of the variable.
But, you could use the fact that functions are first-class objects in javascript to your advantage, depending on what your use case is. Since every function object has the "name" property which is set to the name of the function, you could do:
var obj = function obj(){ return {a:1,b:2,c:3}; };
console.log("obj.name is: " + obj.name);
> "obj.name is obj"
Notice that I assigned a named function to obj
rather than the more common anonymous function--because anonymous functions do not have a name value.
var obj = function(){ return {a:1,b:2,c:3}; };
console.log("obj.name is: " + obj.name);
> "obj.name is: "
So in this way you have an object with a name value accessible as a string. But there's a caveat. If you want to access the value you have to invoke the function:
console.log(obj());
> {a: 1, b: 2, c: 3}
This is because the variable is referencing a function, not the value returned by the function:
console.log(obj);
> function obj(){ return {a:1,b:2,c:3}; }
Note that this technique still doesn't give you the name of the variable because you could assign obj
to another variable named jbo
:
var obj = function obj(){ return {a:1,b:2,c:3}; };
console.log("obj.name is: " + obj.name);
var jbo = obj;
console.log("jbo.name is: " + jbo.name);
> "obj.name is obj"
> "jbo.name is obj"
Get object class from string name in javascript
Don't use eval()
.
You could store your classes in a map:
var classes = {
A: <object here>,
B: <object here>,
...
};
and then just look them up:
new classes[name]()
Get object property name as a string
Yes you can, with a little change.
function propName(prop, value){
for(var i in prop) {
if (prop[i] == value){
return i;
}
}
return false;
}
Now you can get the value like so:
var pn = propName(person,person.first_name);
// pn = "first_name";
Note I am not sure what it can be used for.
Other Note wont work very well with nested objects. but then again, see the first note.
How to get a JavaScript object's class?
There's no exact counterpart to Java's getClass()
in JavaScript. Mostly that's due to JavaScript being a prototype-based language, as opposed to Java being a class-based one.
Depending on what you need getClass()
for, there are several options in JavaScript:
typeof
instanceof
obj.
constructor
func.
prototype
,proto
.isPrototypeOf
A few examples:
function Foo() {}
var foo = new Foo();
typeof Foo; // == "function"
typeof foo; // == "object"
foo instanceof Foo; // == true
foo.constructor.name; // == "Foo"
Foo.name // == "Foo"
Foo.prototype.isPrototypeOf(foo); // == true
Foo.prototype.bar = function (x) {return x+x;};
foo.bar(21); // == 42
Note: if you are compiling your code with Uglify it will change non-global class names. To prevent this, Uglify has a --mangle
param that you can set to false is using gulp or grunt.
In JavaScript how can I retrieve class from it's string name?
There is eval
keyword that works in my Chrome 51.0.2704.103. No need to make global map of classes.
var className = "X";
var klass = eval(className);
var x2 = new klass;
x2.work(1, "Hello", false);
Get the name of an object's type
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. :)
Related Topics
Get Loop Counter/Index Using For…Of Syntax in JavaScript
Dynamically Arrange Some Elements Around a Circle
How to Close a Dropdown on Click Outside
How to Stop a Window.Setinterval in JavaScript
JavaScript - Return String Between Square Brackets
JavaScript - Difference Between Array and Array-Like Object
Safe Evaluation of Arithmetic Expressions in JavaScript
Google Maps JavaScript API Referernotallowedmaperror
"Var" or No "Var" in JavaScript's "For-In" Loop
How to Put an Image File in a JSON Object
Best Practice for Using Window.Onload
Three.Js:2Xmeshes Using Same Vector as Position
What Are the Current Cookie Limits in Modern Browsers
Which Browsers Support Import and Export Syntax for Ecmascript 6