marirena
marirena

Reputation: 308

Javascript inherited class constructor issue

I want to create a subclass from a superclass using prototypes in javascript, so I set them up:

var SuperClass = function() {
    this.a = 1;
    this.get = function() {return this.a;}
    this.init = function() {
        CreateStrangeThings();
    }
    this.init();
}
var SubClass = function() {
    this.b = 2;
    this.get = function() {return this.b;}
}
SubClass.prototype = new SuperClass();

The problem is, the line SubClass.prototype = new SuperClass(); calls the CreateStrangeThings(); function. I want this function to be called only when I create the subclass object (var subOjbect = new SubClass();)

How to overcome this issue? Maybe I should use SubClass.prototype = SuperClass; ? Is it wise?

EDIT:

SubClass.prototype = SuperClass;

removes "a" property from SubClass

Upvotes: 0

Views: 303

Answers (1)

T.J. Crowder
T.J. Crowder

Reputation: 1075567

The problem is, the line SubClass.prototype = new SuperClass(); calls the CreateStrangeThings(); function.

Yes. That's why that pattern, despite being often-cited, is wrong. Another reason is that it ignores the possibility the superclass constructor may require arguments.

Instead, create the prototype object without calling the super constructor:

SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;

...and also call the super constructor inside SubClass:

var SubClass = function() {
    SuperClass.call(this);
    this.b = 2;
    this.get = function() {return this.b;}
};

So all together we get:

var SuperClass = function() {
    this.a = 1;
    this.get = function() {return this.a;}
    this.init = function() {
        CreateStrangeThings();
    }
    this.init();
};
var SubClass = function() {
    SuperClass.call(this);
    this.b = 2;
    this.get = function() {return this.b;}
};
SubClass.prototype = Object.create(SuperClass.prototype);
SubClass.prototype.constructor = SubClass;

Or of course, use ES2015 and a transpiler.

class SuperClass {
    constructor() {
        this.a = 1;
        this.get = function() {return this.a;};
        this.init = function() {
            CreateStrangeThings();
        };
        this.init();
    }
}
class SubClass {
    constructor() {
        super();
        this.b = 2;
        this.get = function() {return this.b;};
    }
}

How to overcome this issue? Maybe I should use SubClass.prototype = SuperClass; ? Is it wise?

No. If you want objects created via new SubClass to inherit properties from SuperClass.prototype, you need SubClass.prototype to use SuperClass.prototype as its prototype. SuperClass doesn't; the prototype of SuperClass is Function.prototype, not SubClass.prototype. (Ignore the name of the prototype property on functions; it isn't their prototype, it's the prototype new assigns to objects created via new TheFunction.)

Upvotes: 2

Related Questions