我有一个带构造函数的抽象Typescript类。这个构造函数接受一个对象,然后试图用对象中的数据设置类的属性。
export default class AbstractModel {
constructor(properties: object) {
Object.assign(this, properties);
}
}
字符串
然后有几个类继承了这个AbstractModel
类,例如:
import AbstractModel from "./abstract-model";
export default class Derived extends AbstractModel {
firstname!: string;
lastname!: string;
age: number = 1;
}
型
我的假设是,当我创建一个新的Derived
并在构造函数中传递{age: 10}
时,新创建的Derived
会将age
设置为10
。但是,age似乎总是1
的初始值。其他没有初始值的属性也会按预期设置。
const derived = new Derived({firstname : "John", lastname: "Doe", age: 10});
型
输出量:
Derived {
firstname: 'John',
lastname: 'Doe',
age: 1,
}
型
将其记录在AbstractModel
的构造函数中,得到以下输出
export default class AbstractModel {
constructor(properties: object) {
Object.assign(this, properties);
console.log(this);
}
}
型
输出量:
Derived {
firstname: 'John',
lastname: 'Doe',
age: 10,
}
型
将其记录在Derived
的构造函数中,得到以下输出
export default class Derived extends AbstractModel {
firstname!: string;
lastname!: string;
age: number = 1;
constructor(properties: object) {
super(properties);
console.log(this);
}
}
型
输出量:
Derived {
firstname: 'John',
lastname: 'Doe',
age: 1,
}
型
有谁能告诉我为什么它会这样做?
1条答案
按热度按时间2ledvvac1#
您为
age
提供的初始值由您的子类构造函数赋值/定义<$。该赋值/定义在子类构造函数中调用super
之后完成(如果你提供了显式的构造函数,或者如果你没有提供,那么就是默认生成的构造函数)。因此,age
在你的子类中将是1
,因为超类构造函数完成的赋值会被覆盖。这里有一个更简单的例子(只使用JavaScript,这样我们就可以在Stack Snippets中运行它):字符串
Derived
的生成构造函数是:型
..并且将
age
设置为1
的定义/赋值<$发生在super(...args)
部分之后。我认为在您所展示的代码中修复它的最小更改方法是删除默认值并为
Derived
提供一个构造函数:型
或
型
或类似的(Playground链接)。
也就是说,
AbstractModel
构造函数代码不是类型安全的,它会复制你提供给它的对象的所有属性,你可能需要重构它。X1 m10n1x是否进行赋值(实际上,
this.age = 1
)或重新定义(Object.defineProperty(this, "age", {value: 1, /*...*/})
)依赖于useDefineForClassFields
配置选项。当该选项未启用时,它会进行赋值,当该选项启用时,它会进行重定义。重定义是JavaScript的类字段标准化的方式,因此,当类字段被引入JavaScript时,TypeScript中添加了配置选项来支持新的标准行为。