4

I have a base class like:

Stage.js:

function Stage(name) {
  this.my_name = name;
}

Stage.prototype.name = function() {
  return this.my_name;
}

module.exports = Stage;

Parallel:

var Stage = require("./Stage");

ParallelStage.prototype = Stage.prototype;

ParallelStage.prototype.execute = function() {
  console.log("+++ Executing stage " + this.name()+ " in parallel...");
  return this;
}

function ParallelStage(name) {
  Stage.call(this,name);
  return this;
}

module.exports = ParallelStage;

and Serial.js:

var Stage = require("./Stage");

SerialStage.prototype = Stage.prototype;

SerialStage.prototype.execute = function() {
  console.log("+++ Executing stage " + this.name()+ " in serial...");
  return this;
}

function SerialStage(name) {
  Stage.call(this,name);
  return this;
}

module.exports = SerialStage;

However when I run:

var Parallel = require ("./ParallelStage");
var Serial = require ("./SerialStage");

var parallel = new Parallel("Extraction");
parallel.execute();

I get the following output:

+++ Executing stage Extraction in serial...

I am clearly missing something fundamental about javascript and prototype inheritance. Can someone clue me into what I am missing here? I was expecting it to show a stage execution in parallel not serial...

RedBullet
  • 501
  • 6
  • 18

4 Answers4

0

You're setting the prototype for both serialStage and ParallelStage to be Stage.prototype, so now you're basically working with the same prototype object for all three methods.

When you write something to that prototype, it overwrites anything that might have the same name, for instance

var Stage = function Stage() {}

ParallelStage.prototype = Stage.prototype; // set to Stage.prototype
ParallelStage.prototype.execute = function() {} 
// ^ you've attached an "execute" method to the Stage.prototype object


SerialStage.prototype = Stage.prototype; // set to the same Stage.prototype
SerialStage.prototype.execute = function() {}
// ^ you've just overwritten the "execute" function in Stage.prototype

You could use Object.create, Object.assign and a number of other solutions to create a copy of the prototype object, so as to not overwrite it's properties each time, but that sorta defeats the purpose of inheriting it in the first place.

adeneo
  • 312,895
  • 29
  • 395
  • 388
0

For proper prototype inheritance you have to use

var child.prototype = Object.create(parent.prototype, {...object with properties/methods...}

When you call

SerialStage.prototype = Stage.prototype;

You loose SerialStage.prototype object as it referenced to Stage.prototype and as result your last inherited object always override properties and method of prototype. So edit you code and change ways of inheriting

ParallelStage.prototype = Object.create(Stage.prototype);

and

ParallelStage.prototype = Object.create(Stage.prototype);
Ruben Nagoga
  • 2,178
  • 1
  • 19
  • 30
0

When you do:

SerialStage.prototype = Stage.prototype;

you're not creating a copy of the base prototype - it's an assignment, and like any other assignment it points at the existing object. So instead of giving unique prototypes to ParallelStage and SerialStage, you're reusing the same prototype for both constructors. And when you assigned the execute method you've overwritten the existing once, not created a new one.

A quick and easy fix would be to do this instead:

ParallelStage.prototype = new Stage();

and

SerialStage.prototype = new Stage();

This creates a new object for each prototype, which you can then put the methods on. Prototype delegation will ensure that property lookups go up the prototype chain.

Chris Tavares
  • 29,165
  • 4
  • 46
  • 63
0

The problem is how you are using Stage's prototype in the following line:

ParallelStage.prototype = Stage.prototype

ParallelStage.prototype is now just a pointer to Stage.prototype. When you modify it you are replacing the parent's function for all objects using the Stage prototype.

Your specific problem occurs because Serial.js is executed after Stage.js and Parallel.js; it's changes to Stage.prototype are the last ones and are in effect for any objects of type Stage, SerialStage and ParallelStage.

The correct way to inherit a prototype from a parent (or one of the correct ways) is to use the following:

Child.prototype = Object.create(Parent.prototype)

Change your code to use this pattern and you should get the behavior you're after.