类的属性的装饰器,是只有两个参数的。
- target 是Test的property
- key是属性的名字
function nameDecorator(target: any, key: string) {
console.log(target, key);
};
class Test{
@nameDecorator
name = 'yang';
}
const test = new Test();
console.log(test.name);
- 类的属性的装饰器,是没有
descriptor
这个参数的,所以默认情况下,我们可以去修改属性。但是我们可以通过装饰器写一个descriptor给类的属性。
// 注意 nameDecorator 返回值要么是 void 要么是 any
function nameDecorator(target: any, key: string):any {
const descriptor: PropertyDescriptor = {
writable: false
};
return descriptor;
};
class Test{
@nameDecorator
name = 'yang';
}
const test = new Test();
test.name = 'weiyang';
console.log(test.name);
- 我们通过装饰器返回的新的descriptor,调换屌属性的老的descriptor,这个时候,如果我们再去修改属性的值,就会报错。
通过属性装饰器,直接对属性值进行修改。
- 在装饰器里,直接通过 target[key]的方式修改属性的值,其实是修改的 类的
原型对象上的属性
,也就是 Test.prototype.name的值。而不是实例上的name。所以我们去访问test.name的时候,还是yang。
function nameDecorator(target: any, key: string):any {
target[key] = 'lee'
};
class Test{
@nameDecorator
// 我们这里定义的属性,实际上是定义在类声明的实例上的
name = 'yang';
}
const test = new Test();
// 访问test.name 是先从实例内容去找,如果找不到,才会去原型内去找。
console.log(test.name); // yang
console.log((test as any).__proto__.name); //lee
也就是说,使用属性装饰器,想要直接对属性的值做改变,是不行的。
网友评论