Hello,
I'm trying to do something with function.prototype.call
to ensure a dynamic inheritance.
Here's a basic example what I'm trying to do:
class Person {
constructor(name, test) {
this.name = name;
this.test = test;
}
}
class Police {
constructor(name, badge, ...manyArgs) {
//Attempt 1:
Person.call(this, name, 'hello world');
//I also tried:
Person.constructor.call(this, name, 'hello world');
console.log(this.test); //This should print a log message of 'hello world'
}
}
The first attempt doesn't work because a class is not a function, and only functions have the call method in their prototype.
The second attempt doesn't give an error, but just doesn't inherit the test value set in Person
.
Something that does work is if I would change the Person
class to:
function Person(name, test) {
this.name = name;
this.test = test;
}
But unfortunately I don't have the luxery to change the class' code that I'm trying to inherit like this.
I've searched online a lot, but couldn't find why the call
function wouldn't work for class
-based classes. It's confusing for me because you can easily rewrite class
-based classes to function
-based classes.
Does anyone have an idea of how to use the prototype.call
method to inherit a class?
CodePudding user response:
Class constructors in JavaScript can only be called with new
, Reflect.construct
orsuper
in a class extension. This tightens up and standardizes alternatives construction techniques using ordinary function
objects.
Although class
objects are functions and do inherit a call
method, attempting to use className.call(...)
will generate an error similar to
TypeError: class constructors must be invoked with 'new'
First answer: as a result of the above you will not be able to call the constructor of a class using `Function.prototype.call'.
As mentioned in comments, extending a base class is an alternative to creating a constructor function, but when written as a class declaration doesn't provide dynamic inheritance.
However this dosn't prevent you dynamically extending a class expression written inside a factory function. As an example:
class Person {
constructor(name, test) {
this.name = name;
this.test = test;
}
}
// factory function:
function policeExtend(baseClass) {
return class Police extends baseClass {
constructor(name, badge) {
super(name, "'just testing'");
this.badge = badge;
}
};
}
const PolicePerson = policeExtend(Person);
let officer = new PolicePerson("chief", 100);
console.log( officer.name, officer.badge, officer.test)
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>