Jesse Aldridge
Jesse Aldridge

Reputation: 8149

Get name of derived constructor in Javascript

Is it possible to get the name of the derived "class" in the following example? I'd like to somehow have the output be "ChildClass", but instead it's "ParentClass".

function ParentClass() { this.name = 'Bob' }
function ChildClass() { this.name = 'Fred' }
ChildClass.prototype = Object.create(ParentClass.prototype);

var child_instance = new ChildClass()
console.log('ChildClass type:', child_instance.constructor.name)

I realize I can do this.my_type = 'ChildClass' in the ChildClass constructor, but I have many classes that extend ParentClass and doing this everywhere would be inconvenient.

Upvotes: 2

Views: 1644

Answers (1)

Aadit M Shah
Aadit M Shah

Reputation: 74204

The problem in your case is that you're overwriting the prototype property of ChildClass but you're not reseting the constructor property on the new prototype. You need to add one extra line:

function ParentClass() {
    this.name = "Bob";
}

function ChildClass() {
    this.name = "Fred";
}

ChildClass.prototype = Object.create(ParentClass.prototype);

ChildClass.prototype.constructor = ChildClass; // add this line to your code

Now your code will work as expected. The following answer explains why your original code didn't work: https://stackoverflow.com/a/8096017/783743

Personally I don't like writing "classes" like this with the constructor and the prototype dangling separately. It's just too tedious to type, incoherent, a pain on the eyes and difficult to maintain. Hence I use the following utility function to create classes:

function defclass(base, body) {
    var uber = base.prototype;
    var prototype = Object.create(uber);
    var constructor = (body.call(prototype, uber), prototype.constructor);
    constructor.prototype = prototype;
    return constructor;
}

Now you can create classes as follows:

var ParentClass = defclass(Object, function () {
    this.constructor = function () {
        this.name = "Bob";
    };
});

var ChildClass = defclass(ParentClass, function () {
    this.constructor = function () {
        this.name = "Fred";
    };
});

This method has several advantages:

  1. Inheritance and class definition have been combined into one.
  2. The constructor is just another prototype method.
  3. Everything is nicely encapsulated within a single closure.
  4. Calling base class prototype methods is easy.
  5. You can create private static functions easily.

Hope that helps.

Upvotes: 5

Related Questions