Page 1 of 1

JavaScript Objects, get constructor name when inherited?

Posted: Tue Sep 26, 2006 4:06 pm
by Chris Corbyn
Take the code:

Code: Select all

function class1()
{
	this.xxx = 42;
}

function class2()
{
	this.yyy = 10;
}

class2.prototype = new class1;

var obj = new class2;
class2 extends class1. But what code could I put inside *class1* to tell me class2's name?

I mean, I'd like to be able to call obj.getClassName() or something but the code needs to be in the parent class1 since it's an abstract class extended by lots of different classes.

Parsing this.constructor.toString() gives me class1's name but I can't seem to get class2's name from in there unless I put the code inside class2 itself :(

Posted: Tue Sep 26, 2006 5:13 pm
by Weirdan
I doubt you'll be able to do that. Remember, there's no inheritance in JS, just prototype chain inspection.

Posted: Wed Sep 27, 2006 5:36 am
by Chris Corbyn
Weirdan wrote:I doubt you'll be able to do that. Remember, there's no inheritance in JS, just prototype chain inspection.
Yeah that really sucks. I basically tried a few things playing about with information stored in 'prototype' but to no avail. I'll just have to keep with my current way of specifying the name manually via constructor parameter :(

Thanks anyway.

Posted: Wed Sep 27, 2006 6:54 am
by volka
How would you solve this problem in php, java, ... ? Why do you need this information?
I can't tell you a reason, but it feels wrong that there should be standard mechanism for a more general class' constructor to get the name of the more specialized class' object that is created.

Posted: Wed Sep 27, 2006 7:55 am
by Chris Corbyn
volka wrote:How would you solve this problem in php, java, ... ? Why do you need this information?
I can't tell you a reason, but it feels wrong that there should be standard mechanism for a more general class' constructor to get the name of the more specialized class' object that is created.
It's not *needed*. It's for a unit testing framework to display the names of the test cases when they fail ;) Like simpletest does. Not a big deal if the user has to specify manually.

Posted: Thu Sep 28, 2006 5:08 am
by Chris Corbyn
This is how I did it in the end if anyone's interested (you need to use a factory to extend the class anbd return the object).

Code: Select all

function AbstractClassToExtend(childName)
{
    this.name = childName || 'DefaultName'; //The name of the class which extends me

    //Remaining methods here (for example)
    this.x = 0;
    
    this.setX = function(x)
    {
        this.x = x;
    }
}
//Make a factory method (static) to create objects that extend me
AbstractClassToExtend.create = function(childClass)
{
    var childClassName = childClass.toString().replace(/^\s*function\s+(\w+)\s*\((?:.|\s)*$/i, '$1'); //Get the name of the class BEFORE extending
    childClass.prototype = new AbstractClassToExtend(childClassName);
    return new childClass();
}

//Now make an extension for it
function myExtension()
{
    this.getX = function()
    {
        return this.x;
    }
}

//Use the factory to get the object
var myObject = AbstractClassToExtend.create(myExtension);

//Check we do actually have the right name
alert(myObject.name); //myExtension

//etc etc
myObject.setX(42);
alert(myObject.getX());
Tested with FF 1.5, Epiphany, Konqueror, IE 6, Galeon, Opera 8 and 9.