繁体   English   中英

Object.keys 在父类的构造函数中使用时返回空数组

[英]Object.keys returns empty array when used in parent class' constructor

如果任何键与定义为公共实例字段的键匹配,我希望能够将属性分配给我的 object 的实例。

当我在同一个 class 声明中包含此逻辑的构造函数时,这可以正常工作,但是如果此逻辑是从父 class 继承的,它将停止工作。

示例代码:

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"

有没有办法让它工作,所以我可以将constructor逻辑保留在父 class ( SuperClass )中?

问题在于它编译成什么,尤其是设置这个属性foo; 添加:在超级调用之后和自己的构造函数中的任何其他内容之前。

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]
    });
  }
}

而且由于super()调用必须是派生构造函数中的第一件事,因此您没有机会以这种方式定义属性。

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);

这是工作版本,有2个问题。 第一:你需要在子class中调用super,在子构造函数之前将参数传递给父构造。 第二: 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"

这应该解决它。 父 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM