Reputation: 187399
I have an inheritance relationship between two JavaScript classes1
RealTimeChart = function(chartAttributes) {
var chart = new FusionCharts(chartAttributes);
this.appendData = function(data) {
chart.feedData(data);
}
};
RealTimeGauge = function(chartAttributes) {
chartAttributes.type = 'AngularGauge';
// call parent constructor
RealTimeChart.call(this, chartAttributes);
};
// inherit from RealTimeChart
RealTimeGauge.prototype = Object.create(RealTimeChart.prototype);
In RealTimeGauge
I would like to override appendData()
. The implementation of this function in RealTimeGauge
needs to call the parent implementation, is this possible?
It's relatively straightforward to do this if I change appendData
to a prototype function, e.g.
// parent class
RealTimeChart.prototype.appendData = function(data) {
this.chart.feedData(data);
};
// child class
RealTimeGauge.prototype.appendData = function(data) {
console.log("doing custom stuff...");
// call the parent function to add the data to the chart
RealTimeChart.prototype.appendData.call(this, data);
};
However, if I make appendData
a prototype function rather than a privileged function, I also have to make chart
a public property, which I'd rather not do. Is it possible to call the parent implementation of appendData
form RealTimeGauge
if it's a privileged function?
Upvotes: 3
Views: 77
Reputation: 2270
To avoid this issue altogether, you could drop inheritance, and go for composition.
RealTimeChart = function(chartAttributes) {
var chart = new FusionCharts(chartAttributes);
this.appendData = function(data) {
chart.feedData(data);
};
};
RealTimeGauge = function (realTimeChart) {
this.appendData = function (data) {
console.log("doing custom stuff...");
realTimeChart.appendData(data);
};
};
new RealTimeGauge(new RealTimeChart({}));
Using composition results in simpler, more modular code. As you can see in the above code, RealTimeGauge
only depends on the interface of RealTimeChart
, not RealTimeChart
itself, like in your original code. This means that you can substitute anything that has the same interface. The 2 'classes' are now decoupled. At what price? Less code that's more readable. You could go even further and decouple RealTimeChart
from FusionCharts
in the same way.
Upvotes: -1
Reputation: 77029
In the child constructor, after the calling the super constructor, this
holds the priviledged function as an own property.
You can reassign this to a temporary variable and create the wrapping function that will replace super's implementation:
Parent = function() {
var x = 1;
this.work = function(y) {
console.log(x + y);
}
};
Child = function() {
Parent.call(this);
var super_work = this.work
this.work = function(y) {
super_work(y + 10);
}
};
Child.prototype = Object.create(Parent.prototype);
Let's give it a try:
p = new Parent()
p.work(1) # prints 2
c = new Child()
c.work(1) # prints 12
Upvotes: 2