vin*_*ron 8 javascript typescript ecmascript-6 typescript2.0
我正在使用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();
Run Code Online (Sandbox Code Playgroud)
目前的结果:
[ 'Hello', 'Both ?' ]
[ 'World' ]
[ 'Hello', 'Both ?' ]
Run Code Online (Sandbox Code Playgroud)
但我想要 :
[ 'Hello' ]
[ 'World' ]
[ 'Both ?' ]
Run Code Online (Sandbox Code Playgroud)
我有没有重新声明静态bar属性的解决方案吗?
谢谢 !
T.J*_*der 12
最关键的事情都懂static和class是子类的构造函数继承自父类的构造函数.从字面上看.class不只是在构造函数创建的实例之间建立继承,构造函数本身也在继承结构中.
Foo是的原型Son和Daughter.这意味着Daughter.bar 是 Foo.bar,这是一个继承财产.但是你给Son它自己的 bar属性,有自己的数组,所以链接Foo被打破了.
这就是为什么你看到的["Hello", "Both ?"],当你在Foo.bar和Daughter.bar:这是相同的bar,在同一阵列指向.但是,你只能看到["World"]上Son.bar,因为它是一个不同的bar,在不同的阵列指向.
将它们分开,你可能想需要给每个构造自己的bar,但是你可以做什么Nitzan托梅尔建议用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);Run Code Online (Sandbox Code Playgroud)
如果你是新鲜的,这是一个非常令人惊讶的事情,但你的三个类在内存中看起来像这样:
+??>Function.prototype
+???????????????+ |
Foo??????????????????+?+?>| (function) | |
/ / +???????????????+ |
| | | [[Prototype]] |??+ +???????????+
| | | bar |?????????>| (array) |
| | | addBar, etc. | +???????????+
| | +???????????????+ | length: 2 |
| | | 0: Hello |
| +?????????????+ | 1: Both ? |
| | +???????????+
+????????????+ |
| |
+???????????????+ | |
| (function) | | |
+???????????????+ | |
Daughter?????>| [[Prototype]] |??+ |
+???????????????+ |
|
+???????????????+ |
| (function) | |
+???????????????+ |
Son??????????>| [[Prototype]] |?????+ +???????????+
| bar |?????????>| (array) |
+???????????????+ +???????????+
| length: 1 |
| 0: World |
+???????????+
关于OPs代码中行为的非常详细的解释可以在@TJCrowder的回答中找到.
为了避免重新定义静态成员,您可以采用以下方法:
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 ?');
Run Code Online (Sandbox Code Playgroud)
(游乐场代码)
| 归档时间: |
|
| 查看次数: |
7459 次 |
| 最近记录: |