views:

216

answers:

3

For example, compare these two:

function Person(name) {
 this.name = name;
}
var john = new Person('John');
console.log(john.constructor);
// outputs: Person(name)

var MyJSLib = {
 Person : function (name) {
   this.name = name;
 }
}
var john2 = new MyJSLib.Person('John');
console.log(john2.constructor);
// outputs: function()

The first form is useful for debugging at runtime. The 2nd form requires some extra steps to figure out what kind of object you have.

I know that I could write a descriptive toString function or call the toSource method on the constructor to get some more information, but I want the simplest way possible.

Is there a way to do this? Suggestions?

A: 

what you want is the name of the holder in the namespace so.

function getName(namespace, obj) {
  for name in namespace:
    if (namespace[name] == obj) return name;
}
console.log(getNameOf(MyJSLib, john2.constructor));
M. Utku ALTINKAYA
This will absolutely NOT work in the code Keith Bentrup given. For it to work, you should look-up recursively. And that would be extremely slow.
BYK
change the window to whatever the namespace variable is.nothing is recursive here.
M. Utku ALTINKAYA
Well that is not a good way. And please read what I said: "it SHOULD be recursive" although it is not.
BYK
define good way please, it is the actual name assigned to a variable, there is no other way. since he stated he does not want stingTo like methods return the class name. And where did he mention recursive thing, I do not see namespaces inside others. Even it was a requirement it is only possible to add those namespaces a predefined holder etc. I am nly making a point to show that name is only meaningful in the namespace, it is not a real identifier.
M. Utku ALTINKAYA
Please see my answer and the accepted answer. If you can do something in one step for all conditions and if there is another way which needs recursion to handle all conditions, then the recursive way is of course "bad".
BYK
+2  A: 

If you want to check whether an object is instance of a specific class then simply use "instanceof" keyword to check that. If you explicitly want a name for the constructor(which I really cannot see a point) you may try the code below

var MyJSLib = {
 Person : function Person(name) {
   this.name = name;
 }
}
BYK
Do you mind explaining the -1?
BYK
john2 instanceof MyJSLib.Person returns true. But I guess the OP doesn't want to test against a specific name
Russ Cam
Well I gave the second answer which is the same as CMS's answer who sent it just after me. Thanks bro...
BYK
I didn't downvote you, I was trying to provide additional detail toward your answer
Russ Cam
So whoever did, thanks to him then =) And a "real" and a big thank you for trying to explain ;)
BYK
+3  A: 

Well that happens because you are using an anonymous function.

You can specify names of anonymous functions (yes, it sounds odd), you could:

var MyJSLib = {
 Person : function Person (name) {
   this.name = name;
 }
}
var john2 = new MyJSLib.Person('John');
console.log(john2.constructor);

Anonymous functions can be named but those names are only visible within the functions themselves, and since you use the new operator, the constructor property will be set, and you will be able to see the name.

You could also compare the constructor reference using or not a name for the function:

console.log(john2.constructor === MyJSLib.Person); // true
CMS
+1, thx! I didn't try that, and I would have assumed (incorrectly) that form would introduce the Person constructor into the global namespace. Good to know.
Keith Bentrup
You're welcome, that form is also often useful when you use recursion on anonymous functions, you have a function name inside the function that refers to itself, more readable than call arguments.callee...
CMS
Anonymous functions are anonymous for a reason :) What you have on the right hand side of this property assignment is merely a function expression (which by definition can have optional identifier)
kangax