使用decorator将属性分配给非原型
Assigning properties to non-prototype with decorators
我正在前端/后端数据结构之间构建一个简单的映射。为了做到这一点,我创建了一个装饰器,看起来如下:
function ApiField(
apiKey: string,
setFn: (any) => any = (ret) => ret,
getFn: (any) => any = (ret) => ret
) {
return function (target: AbstractModel, propertyKey: string) {
target.apiFieldsBag = target.apiFieldsBag || {};
_.assign(
target.apiFieldsBag,
{
[propertyKey]: {
apiKey: apiKey,
setFn: setFn,
getFn: getFn
}
}
);
};
}
这就是我使用它的方式:
class AbstractCar {
@ApiField('id')
public id: string = undefined;
}
class BMW extends AbstractCar {
@ApiField('cylinders')
public cylinderCount: number;
}
class VW extends AbstractCar {
@ApiField('yearCompanyFounded')
public yearEstablished: number;
}
我看到的问题是,实际的对象不是传递给装饰器的,而是它的原型:
__decorate([
ApiField('yearCompanyFounded')
], VW.prototype, "yearEstablished", void 0);
这意味着,当我在decorator中为实例分配东西时,它总是附加到原型,这反过来意味着我想要定义的属性——只有VW
实例——在AbstractCar
和BMW
类上也可用(在本例中,它将是yearEstablished
)。这使得在两个不同的类中不可能有两个具有相同名称但不同API字段的属性。
有没有办法规避这种行为?
现在,所有三个类都在向同一对象添加属性。解决此问题的关键是克隆target.data
上的对象,以便每个类使用不同的对象,而不是所有类都引用同一个对象。
下面是一个更简单的例子,演示了一种方法:
function ApiField(str: string) {
return function (target: any, propertyKey: string) {
// I tested with Object.assign, but it should work with _.assign the same way
target.data = _.assign({}, target.data, {
[propertyKey]: str
});
};
}
class AbstractCar {
@ApiField("car")
public carID;
}
class BMW extends AbstractCar {
@ApiField("bmw")
public bmwID;
}
class VW extends AbstractCar {
@ApiField("vw")
public vwID;
}
AbstractCar.prototype.data; // Object {carID: "car"}
BMW.prototype.data; // Object {carID: "car", bmwID: "bmw"}
VW.prototype.data; // Object {carID: "car", vwID: "vw"}
问题是类中的public
不是标准的JavaScript,它只是TypeScript所做的事情。因此,你必须小心,因为你所做的任何事情都可能在未来破裂。
一种可能性是使用Object.assign()
添加实例属性(IINM,apiFieldsBag
应该从对象文字创建的对象转移到this
):
class AbstractCar {
constructor() {
Object.assign(this, {
@ApiField('id')
id: undefined,
});
}
}
相关文章:
- Javascript原型通用Enquries和通过数组索引分配Id
- 将函数分配为原型函数的属性
- JS继承和原型分配
- Javascript:分配给对象或数组原型会导致括号不起作用
- 在不为原型分配属性的情况下扩展Javascript对象
- 将方法分配给函数内部或外部原型之间的差异
- 为什么可以't我使用原型将函数分配给变量
- 在 Javascript 中创建子类时,为什么要分配原型字段
- 为什么可以't我给“t”分配一个新值;这个“;在原型函数中
- 可以't在分配原型后访问构造函数
- 在分配原型之前,属性值是如何可用的
- 使用decorator将属性分配给非原型
- 函数没有分配给另一个函数'Chrome中的原型
- 为什么子类型必须为其分配父类型's子类型之外的原型's函数
- 使用名称空间将原型对象分配给对象中的匿名函数,这是未定义的
- 当我将原型分配给函数时,我得到了不想要的输出
- Javascript和函数原型分配
- JavaScript原型分配
- 将函数内部原型分配给函数原型对象
- 您可以将一个构造函数的原型分配给另一个构造函数吗?