TypeScriptを使用していますが、クラス間の静的継承に問題があります
誰かが私に次の結果を説明できますか?
class Foo {
protected static bar: string[] = [];
public static addBar(bar: string) {
this.bar.Push(bar);
}
public static logBar() {
console.log(this.bar);
}
}
class Son extends Foo {
protected static bar: string[] = [];
}
class Daughter extends Foo {}
Foo.addBar('Hello');
Son.addBar('World');
Daughter.addBar('Both ?');
Foo.logBar();
Son.logBar();
Daughter.logBar();
現在の結果:
[ 'Hello', 'Both ?' ]
[ 'World' ]
[ 'Hello', 'Both ?' ]
でも私はしたい :
[ 'Hello' ]
[ 'World' ]
[ 'Both ?' ]
静的bar
プロパティを再宣言せずに解決策はありますか?
よろしくお願いします!
OPコードの動作の非常に詳細な説明は、@ T.J.Crowderの このスレッドでの回答 にあります。
静的メンバーを再定義する必要を回避するには、次の方法を使用できます。
class Foo {
private static bar = new Map<string, string[]>();
public static addBar(bar: string) {
let list: string[];
if (this.bar.has(this.name)) {
list = this.bar.get(this.name);
} else {
list = [];
this.bar.set(this.name, list);
}
list.Push(bar);
}
public static logBar() {
console.log(this.bar.get(this.name));
}
}
class Son extends Foo {}
class Daughter extends Foo {}
Foo.addBar('Hello');
Son.addBar('World');
Daughter.addBar('Both ?');
( 遊び場のコード )
static
とclass
について理解しておくべき重要なことは、サブクラスのコンストラクター関数がスーパークラスのコンストラクター関数から継承されることです。文字通り。 class
はjustコンストラクターによって作成されたインスタンス間の継承を設定しません。コンストラクターthemselvesも継承構造。
Foo
は、Son
およびDaughter
のプロトタイプです。つまり、Daughter.bar
isFoo.bar
、それは継承されたプロパティです。しかし、Son
にownbar
プロパティを独自の配列で指定したため、Foo
とのリンクが壊れています。
そのため、["Hello", "Both ?"]
を見るとFoo.bar
およびDaughter.bar
:同じbar
で、同じ配列を指します。しかし、あなただけが["World"]
オン Son.bar
、それは別の配列を指す別のbar
だからです。
それらを分離するには、おそらく各コンストラクタに独自のbar
を指定する必要がありますが、couldは、 Nitzan Tomerの提案Map
。
物事がどのように構成されているかについてもう少し詳しく。それはこのような少しです:
const Foo = {};
Foo.bar = [];
const Son = Object.create(Foo);
Son.bar = []; // Overriding Foo's bar
const Daughter = Object.create(Foo);
Foo.bar.Push("Hello");
Son.bar.Push("World");
Daughter.bar.Push("Both ?");
console.log(Foo.bar);
console.log(Son.bar);
console.log(Daughter.bar);
これは、新鮮なものになると非常に驚くべきことですが、3つのクラスは次のように見えます。
+-> Function.prototype + −−−−−−−−−−−−−−− + | Foo −−−−−−−−− −−−−−−−−− + − + −> | (機能)| | // + −−−−−−−−−−−−−−− + | | | | [[プロトタイプ]] |-+ + −−−−−−−−−−− + | | |バー| −−−−−−−−−> | (配列)| | | | addBarなど| + −−−−−−−−−−− + | | + −−−−−−−−−−−−−−− + |長さ:2 | | | | 0:こんにちは| | + −−−−−−−−−−−−− + | 1:両方? | | | + −−−−−−−−−−− + + −−−−−−−−−−−− + | | | + −−−−−−−−−−−−−−− + | | | (機能)| | | + −−−−−−−−−−−−−−− + | | 娘---------> | [[プロトタイプ]] |-+ | + −−−−−−−−−−−−−−− + | | + −−−−− −−−−−−−−−− + | | (機能)| | + −−−−−−−−−−−−−−− + | 息子-------------------> | [[プロトタイプ]] | −−−−− + + −−−−−−−−−−− + |バー| −−−−−−−−−> | (配列)| + −−−−−−−−−−−−−−−− + + −−−−−−−−−−− + |長さ:1 | | 0:世界| + −−−−−−−−−−− +