Calling parent implementations of privileged functions
I have an inheritance relationship between two JavaScript classes 1
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
must call the parent implementation, is it possible?
It is relatively easy to do this if I change appendData
to a prototype function for example.
// 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 create appendData
a prototype function and not a privileged function, I also need to make a chart
public property, which I would rather not do. Is it possible to call the parent implementation of the form appendData
RealTimeGauge
if it is a privileged function?
- I know they are not classes, but I don't know a better name for them.
source to share
In the child constructor, after the super constructor this
is called, contains the privileged function as its own property.
You can reassign this to a temporary variable and create a wrapping function that will replace the super 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 try to try:
p = new Parent()
p.work(1) # prints 2
c = new Child()
c.work(1) # prints 12
source to share
To avoid this problem, you can opt out of inheritance and go to 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 from the above code, it RealTimeGauge
only depends on the interface RealTimeChart
, not on RealTimeChart
as in your original code. This means that you can replace anything that has the same interface. 2 'classes' are now untied. At what price? Less code that's more readable. You can go even further and separate RealTimeChart
from FusionCharts
the same way.
source to share