I have a component system that should extend from a base object called component
.
New components can be registered via a function called registerComponent()
. This function takes one parameter - the child class - and should inject the parent class component
into it.
The following code almost handles this scenario, with the problem, that the component
constructor is never called:
// Base component.
function component() {
this.visible = false;
console.log('Construct component.');
}
component.prototype.isVisible = function() {
console.log('visibility:', this.visible);
}
// Custom component that will be extended in a moment.
function button() {
this.caption = 'button';
console.log('Construct button.');
}
// This is the function I need help with:
function registerComponent(obj) {
function dynamicComponent() {
component.call(this);
obj.call(this);
}
dynamicComponent.prototype = Object.create(component.prototype);
obj.prototype = Object.create(dynamicComponent.prototype);
obj.prototype.constructor = obj;
}
// Now we register the button, which should add two things:
// the property "this.visible"
// the method "this.isVisible()"
registerComponent(button);
// The test:
b = new button(); // Output is "Construct button."
// but not "Construct component."
b.isVisible(); // Output is "visibility: undefined"
In the above code the method component.prototype.isVisible()
is correctly injected into the button. However, the constructor is not called, and therefore the property this.visible
is undefined
, instead of false
.
What am I missing here?
I think you're looking for
// This is the function I need help with:
function registerComponent(obj) {
function dynamicComponent() {
component.call(this);
obj.call(this);
}
obj.prototype = dynamicComponent.prototype = Object.create(component.prototype);
obj.prototype.constructor = dynamicComponent;
return dynamicComponent;
}
const button = registerComponent(function() {
this.caption = 'button';
console.log('Construct button.');
});
const b = new button();
You cannot alter an existing button
function to make it implicitly call component
.