Let's take the following example code:
var ns = {}; // Some namespace
ns.Test = function()
{
// Constructor of class Test
};
var inst = new ns.Test();
var className = hereIsTheMagic(inst); // Must return "ns.Test"
So I create a class named 'Test' in namespace 'ns' and an instance of this class named 'inst'. Now I want to find out the class name. How can I do this?
Up to now I solved this problem by giving each class a string property with the class name so I could use inst.constructor.className
to access the class name. But if possible I would like to stop doing this because it is pretty error-prone when copy/pasting classes.
If there is no solution which works in all current browsers maybe there is at least some new feature in some future ECMAScript spec which provides access to class names?
Let's take the following example code:
var ns = {}; // Some namespace
ns.Test = function()
{
// Constructor of class Test
};
var inst = new ns.Test();
var className = hereIsTheMagic(inst); // Must return "ns.Test"
So I create a class named 'Test' in namespace 'ns' and an instance of this class named 'inst'. Now I want to find out the class name. How can I do this?
Up to now I solved this problem by giving each class a string property with the class name so I could use inst.constructor.className
to access the class name. But if possible I would like to stop doing this because it is pretty error-prone when copy/pasting classes.
If there is no solution which works in all current browsers maybe there is at least some new feature in some future ECMAScript spec which provides access to class names?
Share Improve this question asked Mar 16, 2011 at 13:39 kayahrkayahr 22.1k30 gold badges105 silver badges148 bronze badges 4- don't sure this is possible, but my question is why you trying to do this? Mostly it will ruin off your OOP – Frizi Commented Mar 16, 2011 at 13:49
- @Frizi: I can't speak for kayahr, but it can be useful for error reporting. – T.J. Crowder Commented Mar 16, 2011 at 13:50
-
@Frizi: I need this primarily for object serialization/deserialization. I just found out that Safari supports a special
displayName
property which is used to name anonymous functions in the profiler. So maybe it's a good idea to use this, too. So first check forname
and if this is not there then check fordisplayName
which I have to set manually for all classes. – kayahr Commented Mar 16, 2011 at 15:01 - I use AS3, and it has a typeof operator to return the class name, so I have a Json.stringify method now that can handle circular references and stores all the object type names so it can revive the entire object graph back to its original state, plete with strongly-typed instances. It's patible with JSON.NET too, so I can stringify something in Flash, send it to .NET and revive the instance on the server. Class definitions are mirrored on the server in .NET and a custom type resolver handles special type name mapping (e.g. AS3 'Object' revived as .NET 'System.Dynamic.ExpandoObject'. – Triynko Commented Aug 22, 2013 at 21:52
1 Answer
Reset to default 8JavaScript doesn't have classes, it has constructor functions and the prototype chain. Together, they can look a bit like classes, but they really aren't. :-)
No, there's no standard way that hereIsTheMagic
can find the string "ns.Test" in your example, not even in ECMAScript 5. For one thing, ns.Test
may not be the only property referring to that function (what if you added ns.OtherTest = ns.Test;
, for instance).
JavaScript does have the concept of functions having proper names, but there's no standard way to access the proper name of a function, and even if you could, the function you're calling ns.Test
is anonymous. The property you've assigned it to on ns
has a name (Test
), but the function does not.
You could give the function a name:
var ns = {}; // Some namespace
(function() {
ns.Test = ns_Test;
function ns_Test() {
// Constructor of class Test
}
})();
...which is a good idea, because it helps tools help you, but there's no standard way for JavaScript code itself to get at that name. (Don't do ns.Test = function ns_Test() { ... };
, though. It should work, but there are various implementations of ECMAScript that have various bugs related to it. More about that in the article linked above.)
Update: I probably should have said: There are non-standard ways to get at the proper name of a function (ns_Test
in my example above).
The easiest of these is the name
property on function instances, which is supported by many implementations, including:
- Firefox's SpiderMonkey
- Chrome's V8
- Opera's engine (I don't know its name)
- Safari's engine (including Safari mobile)
...so alert(ns_Test.name);
would alert "ns_Test". But it is non-standard and not supported by any version of JScript (Microsoft's engine), not even the version used by IE9 (now finally released!). Here's a quick tester page: http://jsbin./oxuva3
Note that, again that's the proper name of the function (see my example above), not the name of the property you've assigned it to.
If name
isn't there, you can use toString()
on the function object, which may (or may not) return a string representation of the function (e.g., "function ns_Test() { ... }"). That's pletely non-standard, but mon on desktop browsers; it doesn't work on several mobile browsers, and probably a bad idea in any case. :-)