簡體   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