[英]ES6 classes: is it possible to access the constructor of a child class from the parent?
[英]ES6, access props set by the child from the parent's constructor
我試圖用ES6類建立一個類層次結構。
所有實體都將從單個Base
類繼承。 它需要以通用方式訪問Child
類公開的屬性。 像這樣:
class Base {
constructor() {
this.doSomethingWithProps();
}
doSomethingWithProps() {
console.log(Object.keys(this));
}
}
class Entity extends Base {
constructor() {
super();
this.key = "value";
}
}
顯然,在上面的示例中, Base
類將看不到Entity
設置的key
道具。 理想情況下,我this
分配移到super()
之前,但這是不允許的。 能夠在構造函數之前設置屬性也很好,但是AFAIK也是不可能的。
我剩下的唯一解決方案是在每個Entity
執行以下操作:
class Base {
doSomethingWithProps() {
console.log(Object.keys(this));
}
}
class Entity extends Base {
constructor() {
super();
this.key = "value";
this.doSomethingWithProps();
}
}
但是,除了不盡如人意之外,如果我隨后想從Entity
繼承,也會造成問題。 然后, doSomethingWithProps
將需要能夠檢測它是否是調用層次結構中的“最頂層”方法,然后才執行其操作。 實現這一目標 (我能想到)的唯一方法將涉及更多樣板。
有什么解決方案我想念嗎? 我願意在需要時使用其他OOP模式,盡管我希望盡可能與本機ES6類保持聯系。
您試圖做的事情是完全不可能的。 父級初始化始終在子級初始化之前運行,因此,父級構造函數必須不依賴於可能會被子級覆蓋的屬性。 順便說一句,這是一個與語言無關的問題。
解決方案是使用構造函數的參數,這些參數可以在到達父代碼之前在子代中進行修改:
class Base {
constructor(key) {
this.key = key;
// do something with key
}
}
class Entity extends Base {
constructor() {
super("value");
}
}
console.log(new Entity);
或更通用
class Base {
constructor(props) {
this.doSomething(props);
Object.assign(this, props);
}
doSomething(props) {
return Object.keys(props);
}
}
class Entity extends Base {
constructor() {
super({key: "value"});
}
}
console.log(new Entity);
還要注意,構造函數應始終是純凈的。 它們的唯一目的是從參數初始化新實例,並且不執行其他任何副作用。 構造函數通常不需要調用任何(可重寫)實例方法(盡管可以使用靜態方法)。
因此,如果在創建實例時仍然需要執行類似的操作,則不要在構造函數中執行此操作。 而是在使用構造函數后調用方法:
class Base {
log() {
console.log(Object.keys(this));
return this;
}
}
class Entity extends Base {
constructor() {
super();
this.key = "value";
}
}
var e = new Entity().log();
您還可以將其抽象出來:
class Base {
static createAndLog(...args) {
var x = new this(...args);
x.log();
return x;
}
…
}
…
var e = Entity.createAndLog();
根據您要走的復雜程度,可能有兩條路線可以走。
Base
如果可能,將所需的道具從Entity傳遞到Base並在其中維護狀態。
class Base { constructor(props) { for (var k in props) { this[k] = props[k] } this.doSomethingWithProps(); } doSomethingWithProps() { console.log(Object.keys(this)); } } class Entity extends Base { constructor(props) { super(props); } } let entity = new Entity({key: 'value'}) // ["key"]
Entity
引用傳遞給Base
注意,我錯誤地假設了Entity ..的單獨實例。這過於冗余。
不是那么簡單,並且從技術上講將包含一個自引用鍵,因為Entity
將從Base
繼承child
鍵。 絕對可以認為這是一種“錯誤”的方法,但是我將其包括在內。
class Base { constructor() { this.child } registerChild(child) { this.child = child this.doSomethingWithProps() } doSomethingWithProps() { console.log(Object.keys(this.child)); } } class Entity extends Base { constructor() { super(); this.key = 'value' this.registerChild(this) } } let entity = new Entity() // ["key", "child"]
我認為這里的觀察應該是:避免在構造函數中調用依賴於對象狀態的方法,因為構造函數旨在構建該狀態。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.