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
})
}
演示


谢谢你的解释。