面试题答案
一键面试在TypeScript属性装饰器中,装饰器函数接收三个参数:
- 目标对象(Target):它是一个类的原型对象。当装饰器应用于类的属性时,
Target
指向该类的原型对象。在数据验证场景中,可以通过这个对象来访问类的其他属性或方法,比如验证某个属性的值是否依赖于其他属性,就可以从这个原型对象上获取相关信息。例如:
class User {
@validateAge
age: number;
}
function validateAge(target: any, propertyKey: string) {
let value: number;
const getter = function () {
return value;
};
const setter = function (newValue: number) {
if (newValue < 0 || newValue > 120) {
throw new Error('Invalid age');
}
value = newValue;
};
Object.defineProperty(target, propertyKey, {
get: getter,
set: setter,
enumerable: true,
configurable: true
});
}
这里通过 target
可以操作 age
属性的存取器,实现对 age
数据的验证。
2. 属性名(PropertyKey):它是一个字符串或 Symbol
,表示被装饰的属性的名称。在数据验证中,可以利用这个属性名来记录日志或进行特定属性的针对性验证。例如:
function logProperty(target: any, propertyKey: string) {
console.log(`Validating property: ${propertyKey}`);
}
这样可以在验证开始时打印出正在验证的属性名,方便调试和跟踪。
3. 属性描述符(PropertyDescriptor):这是一个对象,包含了属性的一些元数据,如 value
、writable
、enumerable
和 configurable
等特性。在数据验证中,可以修改这个描述符来改变属性的行为。比如在验证通过后,设置属性为只读:
function makeReadOnlyAfterValidation(target: any, propertyKey: string, descriptor: PropertyDescriptor) {
let value = descriptor.value;
const getter = function () {
return value;
};
const setter = function (newValue: any) {
if (/* 进行验证 */ true) {
value = newValue;
Object.defineProperty(target, propertyKey, {
get: getter,
set: null,
enumerable: true,
configurable: true
});
} else {
throw new Error('Validation failed');
}
};
descriptor.get = getter;
descriptor.set = setter;
return descriptor;
}
通过修改 PropertyDescriptor
,在验证成功后将属性设置为只读。