puppeteer701
puppeteer701

Reputation: 1285

Extending prototype with another prototype

I would like to extend a Prototype with another Prototype. This is my current code, tried also different things, and I cannot get it to work.

Network.prototype is an empty object, why?

function Tester() {}

Tester.prototype = {
	clazz: 'Tester',
	start: function (url) {}
};


function NetworkTester() {}

NetworkTester.prototype = {
	clazz: 'NetworkTester',
        test: function (url) {
           this.start(); // this is undefined
        }
};


var helpers = {
    extend2: function (ChildClass, ParentClass) {
		ChildClass.prototype = new ParentClass();
		ChildClass.prototype.constructor = ChildClass;
	}
};

helpers.extend2(NetworkTester, Tester);

console.log(NetworkTester.prototype);

I do not want to write NetoworkTester code like this:

NetworkTester.prototype.clazz = 'NetworkTester';
NetworkTester.prototype.test = function (url) {
    this.start(); // this is undefined
};

I want it as I have it, it is prettier.

Upvotes: 0

Views: 69

Answers (1)

nils
nils

Reputation: 27174

Why is this happening?

Because you are overwriting the .prototype property with the following line:

ChildClass.prototype = new ParentClass();

The object created by new ParentClass(); is an object without any own properties (since you aren't assigning any in the constructor of Tester), thus it shows up as an empty Object in the dev tools.

The internal [[Prototype]] slot of NetworkTester.prototype is set though. You can have a look at it using the Object.getPrototypeOf method:

Object.getPrototypeOf(NetworkTester.prototype)

How can this be solved?

To solve your dilemma, you would have to turn around your code order:

  1. Create the new object for the .prototype property of the child, linking it to the parent:

    helpers.extend2(NetworkTester, Tester);
    
  2. Define the .prototype properties of the child:

    NetworkTester.prototype.x = ...;
    NetworkTester.prototype.y = ...;
    

In order to avoid unnecessary constructor calls of the parent, you should probably use Object.create instead of the new operator.

So your code would look like this:

var helpers = {
    extend2: function (ChildClass, ParentClass) {
        ChildClass.prototype = Object.create(ParentClass.prototype);
        ChildClass.prototype.constructor = ChildClass;
    }
};

function Tester() {}

Tester.prototype = {
    clazz: 'Tester',
    start: function (url) {}
};


function NetworkTester() {}

// This needs to happen before you assign to NetworkTester.prototype
helpers.extend2(NetworkTester, Tester);

NetworkTester.prototype.clazz = 'NetworkTester';
NetworkTester.prototype.test = function (url) {
    this.start(); // this is undefined
};

console.log(NetworkTester.prototype);

Upvotes: 1

Related Questions