TypeScript:使用属性装饰器时获取错误的对象
我有一辆带有一些汽车包含牌照信息的汽车,现在我想验证属性牌照,所以我用以下方式使用属性装饰:TypeScript:使用属性装饰器时获取错误的对象,typescript,decorator,typescript-decorator,Typescript,Decorator,Typescript Decorator,我有一辆带有一些汽车包含牌照信息的汽车,现在我想验证属性牌照,所以我用以下方式使用属性装饰: class Car{ @validate public plate: string; public model: string; // extra info constructor(plate: string, model: string){ this.plate= plate; this.model = model;
class Car{
@validate
public plate: string;
public model: string;
// extra info
constructor(plate: string, model: string){
this.plate= plate;
this.model = model;
}
toString(): string{
return `Car: ${this.plate} - ${this.model}`;
}
}
const car1 = new Car('IT123UE', 'Car1Model');
console.log('1 - ', car1.toString());
const car2 = new Car('IT000000UE', 'Car2Model');
console.log('2 - ', car2.toString());
然后我有以下属性装饰器函数:
function validate(target: any, propertyKey: string){
let value = target[propertyKey];
Object.defineProperty(target, propertyKey, {
get: () => value,
set: (newValue) => {
const pattern = /^[A-Z]{2}\s?[0-9]{3}\s?[A-Z]{2}$/;
if(pattern.test(newValue)){
value = newValue;
} else {
console.error('Non valid plate: ', newValue);
//value = undefined;
}
}
})
}
现在,如果我以这种方式测试代码:
class Car{
@validate
public plate: string;
public model: string;
// extra info
constructor(plate: string, model: string){
this.plate= plate;
this.model = model;
}
toString(): string{
return `Car: ${this.plate} - ${this.model}`;
}
}
const car1 = new Car('IT123UE', 'Car1Model');
console.log('1 - ', car1.toString());
const car2 = new Car('IT000000UE', 'Car2Model');
console.log('2 - ', car2.toString());
我得到:
1 - Car: IT123UE - Car1Model
Non valid plate: IT000000UE
2 - Car: IT123UE - Car2Model <-- why print car1.plate if car2.plate is not valid and this is car2 object?
Non valid plate: IT000000UE
2 - Car: undefined - Car2Model <- now is undefinied
1 - Car: IT123UE - Car1Model
我得到:
1 - Car: IT123UE - Car1Model
Non valid plate: IT000000UE
2 - Car: IT123UE - Car2Model <-- why print car1.plate if car2.plate is not valid and this is car2 object?
Non valid plate: IT000000UE
2 - Car: undefined - Car2Model <- now is undefinied
1 - Car: IT123UE - Car1Model
如果car2.plate无效且这是car2对象,为什么要打印car1.plate
简短回答:原因是两个类实例正在访问相同的类原型属性,并且原型属性是类实例之间的共享状态
更长的回答:您的验证
函数是实例属性上的一个函数。TypeScript文档说明实例属性装饰器接收类原型作为第一个参数。因此,在验证器中,您设置的是类原型的plate
属性,而不是特定类实例的属性。因为类实例共享类原型,所以第二个类实例访问第一个实例已经设置的属性值
下面是一个演示,演示了两种方法第二种方法适合您。第一个是您最初对共享原型状态所做的操作。第二个(validateToo
)不使用共享状态;get/set操作的不是目标
,而是此
,get/set不是箭头函数,而是函数,因此它们采用正确的此
对象
等级车{
@证实
公共车牌:字符串;
@验证
公共平台:字符串;
建造师(铭牌:字符串){
这个盘子=盘子;
这个.plateToo=板;
}
}
//第二种方法对您有效
函数validateToo(目标:any,属性key:string){
const fieldKey=`{propertyKey}`;
Object.defineProperty(target,propertyKey{
得到(){
返回此[字段键];
},
设置(新值){
//您可以将验证逻辑放在这里
此[字段键]=新值;
}
})
}
函数验证(目标:任意,属性key:string){
让值=目标[propertyKey];
Object.defineProperty(target,propertyKey{
获取:()=>值,
set:(newValue)=>value=newValue
})
}
演示
谢谢你的解释。