1

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

marirena
  • 300
  • 2
  • 10
  • So why don't you include the `CreateStrangeThings()` function in the `SubClass` constructor? – Redu Oct 16 '16 at 09:56
  • "CreateStrangeThings()" must be initiated in every base class in my application design and should not be repeated in coding (true OOP) – marirena Oct 16 '16 at 10:00
  • `SubClass.prototype = SuperClass` will make nothing but your `SubClass.prototype` a function. Avoid that. Also watch that you are shadowing your `get` function in the prototype chain, which is expected to return `this.a` by the `get` function in the instantiated object which returns `this.b`. Besides, what exactly does `CreateStrangeThings()` do..? – Redu Oct 16 '16 at 10:12
  • Something that shouldn't be done upon setting up the base class. (it creates graphics) – marirena Oct 16 '16 at 10:23
  • 1
    Btw, you should not use an `init` method that you call from your constructor. Instead, put the code directly in the constructor. – Bergi Oct 16 '16 at 18:01

1 Answers1

2

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.)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875