[英]Object.keys returns empty array when used in parent class' constructor
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.如果任何键与定义为公共实例字段的键匹配,我希望能够将属性分配给我的 object 的实例。
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.当我在同一个 class 声明中包含此逻辑的构造函数时,这可以正常工作,但是如果此逻辑是从父 class 继承的,它将停止工作。
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
)?有没有办法让它工作,所以我可以将constructor
逻辑保留在父 class ( SuperClass
)中?
the issue is what this compiles down to, especially the order and where setting this property foo;
问题在于它编译成什么,尤其是设置这个属性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.而且由于super()
调用必须是派生构造函数中的第一件事,因此您没有机会以这种方式定义属性。
imo the best solution would be to move the assign-values logic into an method and call it explicitely AFTER all constructors have run: imo最好的解决方案是将赋值逻辑移动到一个方法中,并在所有构造函数运行后显式调用它:
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.这是工作版本,有2个问题。 First: you need to call super in the child class to pass the parameters to the parent construction before the child constructor.第一:你需要在子class中调用super,在子构造函数之前将参数传递给父构造。 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!第二: Object 中的 this 是指父 Object 所以 foo 将仅在父中定义,删除后,它工作正常!
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 仅使用其自己的及其父 class 公共/受保护变量,但不使用其子变量。
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);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.