I want to be able to assign the properties to instances of my object if any of the keys match the ones defined as a public instance field.
This works fine when I have the constructor containing this logic within the same class declaration but if this logic is inherited from the parent class it stops working.
Example Code:
class SuperClass {
constructor(data = {}) {
Object.keys(this).forEach(key => { this[key] = data[key] });
}
}
class InheritingClass extends SuperClass {
foo;
}
class NonInheritingClass {
// same as above in SuperClass
constructor(data = {}) {
Object.keys(this).forEach(key => { this[key] = data[key] });
}
foo;
}
const parameters = { foo: "bar" };
const nonWorkingInstance = new InheritingClass(parameters);
const workingInstance = new NonInheritingClass(parameters);
console.log(nonWorkingInstance.foo);
// undefined
console.log(workingInstance.foo);
// "bar"
Is there any way to have it work so I can keep the constructor
logic in the parent class ( SuperClass
)?
the issue is what this compiles down to, especially the order and where setting this property foo;
is added: AFTER the super-call and BEFORE anything else in the own constructor.
class SuperClass {
constructor(data = {}) {
console.log(this, this.constructor);
Object.keys(this).forEach(key => {
this[key] = data[key]
});
}
}
class InheritingClass extends SuperClass {
constructor(data = {}) {
super(data);
this.foo = void 0; // <--- here, AFTER the super() call
}
}
class NonInheritingClass {
// same as above in SuperClass
constructor(data = {}) {
this.foo = void 0; // <-- but BEFORE any other code in the own constructor.
console.log(this);
Object.keys(this).forEach(key => {
this[key] = data[key]
});
}
}
And since the super()
call has to be the first thing in a derived constructor you have no chance to define the property in a way that.
imo the best solution would be to move the assign-values logic into an method and call it explicitely AFTER all constructors have run:
class SuperClass {
assign(data = {}) {
Object.keys(this).forEach(key => { this[key] = data[key] });
return this;
}
}
class InheritingClass extends SuperClass {
foo;
}
const parameters = { foo: "bar" };
const nonWorkingInstance = new InheritingClass().assign(parameters);
Here is the working version, 2 problems. First: you need to call super in the child class to pass the parameters to the parent construction before the child constructor. Second: this in Object is referring to the parent Object so foo will be defined only in the Parent, after removing this, it is working fine!
class SuperClass { constructor(data = {}) { Object.keys(data).forEach((key) => { this[key] = data[key]; }); } } class InheritingClass extends SuperClass { constructor(data) { super(data); } } class NonInheritingClass { // same as above in SuperClass constructor(data = {}) { Object.keys(this).forEach((key) => { this[key] = data[key]; }); } foo; } const parameters = { foo: 'bar' }; const nonWorkingInstance = new InheritingClass(parameters); const workingInstance = new NonInheritingClass(parameters); console.log(nonWorkingInstance.foo); // undefined console.log(workingInstance.foo); // "bar"
This should fix it. Parent class only uses its own and its Parent class public/protected variables but not its child variables.
class SuperClass {
constructor(data = {}) {
Object.keys(this).forEach(key => { this[key] = data[key] });
}
foo;
}
class InheritingClass extends SuperClass {}
const parameters = { foo: "bar" };
const nonWorkingInstance = new InheritingClass(parameters);
console.log(nonWorkingInstance.foo);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.