2

Imagine a JavaScript "class" Foo:

var Foo = function()
{
};

And an instance of that class:

var foo = new Foo();

Can I obtain the string Foo directly from the instance foo, or is Foo just a transitive variable that cannot be associated with the instance foo after instantiation?


EDIT 1 SLaks suggests using foo.constructor. This gives:

function ()
{
}

This approach works if the function is defined in the form:

function Foo()
{}

...but this might not always be the case.


EDIT 2 Trying skizeey's approach doesn't work either. It is essentially a more complete attempt as Slack's method, but yields an empty string: ""


EDIT 3 I wonder whether this is actually possible somehow. Notice the following transcript from Chrome's JavaScript console:

> var Foo = function() {}
undefined
> var foo = new Foo();
undefined
> foo
Foo

In the last line, Chrome clearly knows that the object is of type Foo. However this may just be a Chrome thing, and not standard JavaScript or even inaccessible from the language itself.

Community
  • 1
  • 1
Drew Noakes
  • 300,895
  • 165
  • 679
  • 742
  • Do you really need the string `"Foo"`? What are you ultimately trying to do? – I Hate Lazy Oct 21 '12 at 01:54
  • I'm trying to leverage a convention in my code. I'm using RequireJS and knowing this name would mean I'd know what module the class was defined in, so I could load it again upon resaturating data from local storage. – Drew Noakes Oct 21 '12 at 01:57
  • If you control the constructors in the modules being required, you may just need to write the names in. If you don't, then are you hoping to re-associate the data with its original prototype chain? Or is it merely to know which modules to load? – I Hate Lazy Oct 21 '12 at 02:06
  • @user1689607, both in a sense. By reloading the correct module, I'll have access to an instance of the class where the name matches the module. Unless someone can find a way to do this, I'll even have to add my own property to each module that fits this pattern, or change the way I declare my constructors. – Drew Noakes Oct 21 '12 at 02:10
  • Generally I'd suggest using named functions for constructors, if for nothing else, it helps in debugging. You can keep using function expressions, but use named expressions. `var Foo = function Foo() {...};` Though I'd prefer standard declarations. `function Foo(){...}` – I Hate Lazy Oct 21 '12 at 02:21
  • @user1689607, see my third edit. Chrome knows the name of the function even without using named function expressions. – Drew Noakes Oct 21 '12 at 13:20
  • Yeah, I have no idea how Chrome does that but I assume it's some custom behavior, because it certainly isn't part of the language spec. If you make a `Foo` object, but change its prototype so that there's no longer any connection between the object and the original constructor, it still gives you `"Foo"`. Here's a demo: http://jsfiddle.net/n6gCQ/ – I Hate Lazy Oct 21 '12 at 15:10
  • @user1689607, if you want to put your comments into an answer, I'll accept it. – Drew Noakes Oct 22 '12 at 00:45
  • Thanks, but I'm going to throw my support behind @MarkReed's answer. Pretty much cuts to the heart of the issue, and I'm just feeling a little too lazy right now. :) – I Hate Lazy Oct 22 '12 at 01:04

4 Answers4

4

With named function:

> var Foo = function Foo(){};
> undefined
> var foo = new Foo();
> undefined
> foo.constructor.name
> "Foo"

With unnamed function:

> var Foo = function (){};
> undefined
> var foo = new Foo();
> undefined
> foo.constructor.name
> ""
jurassix
  • 1,509
  • 10
  • 10
2

There is no way to achieve what you want without modifying the module code.

When you define a function like

var Foo = function() {...}

The function - and any object created using it as a constructor - has no knowledge of the name Foo. You might as well do var x = 0 and then attempt to get the value 0 to tell you about the name x.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175
  • Take a look at my third edit. Somehow Chrome knows the name of the class, even though it was not from a named function expression. I want to know whether this is something that's part of the standard, or just a privilege that Chrome is flaunting. – Drew Noakes Oct 21 '12 at 13:23
0

You can get the Foo function by from foo.constructor.
However, you cannot associate that function instance with the name of the variable you assign it to.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

From another thread:

var getName = function(object) { 
  var funcNameRegex = /function (.{1,})\(/;
  var results = (funcNameRegex).exec(object.constructor.toString());
  return (results && results.length > 1) ? results[1] : "";
};

You're essentially just grabbing the entire constructor as a string, and then extracting its name.

One caveat though: like what clentfort said on a comment to SLaks' answer, there's no one stopping anyone from overwriting an object's constructor property.

Another caveat: you are also going to have to explicitly name your function, too.

Community
  • 1
  • 1
Sal Rahman
  • 4,607
  • 2
  • 30
  • 43