说说你对TypeScript装饰器的理解及其应用场景?

一、是什么

装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上

是一种在不改变原类和使用继承的情况下,动态地扩展对象功能

同样的,本质也不是什么高大上的结构,就是一个普通的函数,@expression 的形式其实是Object.defineProperty的语法糖

expression 求值后必须也是一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入

二、使用方式

由于typescript是一个实验性特性,若要使用,需要在tsconfig.json文件启动,如下:

{"compilerOptions": {"target": "ES5","experimentalDecorators": true}
}

typescript装饰器的使用和javascript基本一致

类的装饰器可以装饰:

  • 方法/属性
  • 参数
  • 访问器

类装饰

例如声明一个函数 addAge 去给 Class 的属性 age 添加年龄.

function addAge(constructor: Function) {constructor.prototype.age = 18;
}@addAge
class Person{name: string;age!: number;constructor() {this.name = 'huihui';}
}let person = new Person();console.log(person.age); // 18

上述代码,实际等同于以下形式:

Person = addAge(function Person() { ... });

上述可以看到,当装饰器作为修饰类的时候,会把构造器传递进去。 constructor.prototype.age 就是在每一个实例化对象上面添加一个 age 属性

方法/属性装饰
同样,装饰器可以用于修饰类的方法,这时候装饰器函数接收的参数变成了:

  • target:对象的原型
  • propertyKey:方法的名称
  • descriptor:方法的属性描述符

可以看到,这三个属性实际就是Object.defineProperty的三个参数,如果是类的属性,则没有传递第三个参数

如下例子:

// 声明装饰器修饰方法/属性
function method(target: any, propertyKey: string, descriptor: PropertyDescriptor) {console.log(target);console.log("prop " + propertyKey);console.log("desc " + JSON.stringify(descriptor) + "\n\n");descriptor.writable = false;
};function property(target: any, propertyKey: string) {console.log("target", target)console.log("propertyKey", propertyKey)
}class Person{@propertyname: string;constructor() {this.name = 'huihui';}@methodsay(){return 'instance method';}@methodstatic run(){return 'static method';}
}const xmz = new Person();// 修改实例方法say
xmz.say = function() {return 'edit'
}

输出如下图所示:

参数装饰
接收3个参数,分别是:

  • target :当前对象的原型
  • propertyKey :参数的名称
  • index:参数数组中的位置
function logParameter(target: Object, propertyName: string, index: number) {console.log(target);console.log(propertyName);console.log(index);
}class Employee {greet(@logParameter message: string): string {return `hello ${message}`;}
}
const emp = new Employee();
emp.greet('hello');

输入如下图:

访问器装饰
使用起来方式与方法装饰一致,如下:

function modification(target: Object, propertyKey: string, descriptor: PropertyDescriptor) {console.log(target);console.log("prop " + propertyKey);console.log("desc " + JSON.stringify(descriptor) + "\n\n");
};class Person{_name: string;constructor() {this._name = 'huihui';}@modificationget name() {return this._name}
}

装饰器工厂
如果想要传递参数,使装饰器变成类似工厂函数,只需要在装饰器函数内部再函数一个函数即可,如下:

function addAge(age: number) {return function(constructor: Function) {constructor.prototype.age = age}
}@addAge(10)
class Person{name: string;age!: number;constructor() {this.name = 'huihui';}
}let person = new Person();

执行顺序
当多个装饰器应用于一个声明上,将由上至下依次对装饰器表达式求值,求值的结果会被当作函数,由下至上依次调用,例如如下:

function f() {console.log("f(): evaluated");return function (target, propertyKey: string, descriptor: PropertyDescriptor) {console.log("f(): called");}
}function g() {console.log("g(): evaluated");return function (target, propertyKey: string, descriptor: PropertyDescriptor) {console.log("g(): called");}
}class C {@f()@g()method() {}
}// 输出
f(): evaluated
g(): evaluated
g(): called
f(): called

三、应用场景

可以看到,使用装饰器存在两个显著的优点:

  • 代码可读性变强了,装饰器命名相当于一个注释
  • 在不改变原有代码情况下,对原来功能进行扩展

后面的使用场景中,借助装饰器的特性,除了提高可读性之后,针对已经存在的类,可以通过装饰器的特性,在不改变原有代码情况下,对原来功能进行扩展

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: TypeScript 装饰的主要应用场景有以下几种: 1. 类装饰: 用于修改类的行为,例如添加静态属性和方法、重写构造函数等。 2. 方法装饰: 用于修改类中某个方法的行为,例如在方法调用前后执行特定代码、更改方法的返回值等。 3. 访问装饰: 用于修改类中属性访问的行为,例如在获取或设置属性值时执行特定代码等。 4. 属性装饰: 用于修改类中某个属性的行为,例如对属性进行只读设置、验证属性值是否符合要求等 5. 参数装饰: 修改方法/构造函数中参数的属性,例如添加验证,或者标记参数是否可选等。 装饰应用可以使得我们的代码变得更加灵活,并且可以在不改变原有代码结构的情况下对其进行拓展和优化. ### 回答2: TypeScript装饰主要用于在类、方法、属性或参数上添加元数据或额外的逻辑。它是一种特殊类型的声明,可以附加到类声明、方法、属性或参数上,并包含有关这些声明的额外信息。 主要应用场景有以下几个方面: 1. 类装饰:可以用于修改类的行为。比如可以使用类装饰来对类的构造函数进行修改,例如添加新的属性或方法,或者对原有的属性和方法进行修饰。 2. 方法装饰:可以用于修改方法的行为。比如可以使用方法装饰来拦截方法的调用,修改方法参数或返回值,或者在方法执行前后添加额外的逻辑。 3. 属性装饰:可以用于修改类的属性。比如可以使用属性装饰来修改属性的属性描述符,添加属性值的验证和转换逻辑。 4. 参数装饰:可以用于修改方法的参数行为。比如可以使用参数装饰来对方法的参数进行验证、转换或添加元数据。 通过使用装饰,我们可以在不修改原有代码的情况下,动态地扩展和修改类、方法、属性或参数的行为。装饰提供了一种灵活和可复用的方式来实现对代码的注解和修改。它在许多框架和库中都得到了广泛的应用,例如Angular框架中的依赖注入和路由配置等功能就使用了装饰。 ### 回答3: TypeScript装饰是一种特殊类型的声明,可以附加到类、方法、属性或参数上,可以用于修改类的行为或元数据。主要的应用场景包括: 1. 修改类的行为: 装饰可以用于修改类的行为,例如增加类的方法或属性,对类的属性进行校验或者限制等。通过使用装饰,可以在不修改源代码的情况下给类添加额外的功能。 2. 日志记录: 装饰可以用于记录类或方法的调用日志,包括方法的入参和出参。这对于调试和排查问题非常有帮助,可以快速定位问题所在。 3. 访问权限控制: 装饰可以用于控制类的方法或属性的访问权限,例如限制只有特定用户或角色才能访问某个方法或属性。 4. 验证和校验: 装饰可以用于验证和校验类的属性的合法性,例如对用户输入进行校验,确保输入的数据符合规定的格式和要求。 5. 依赖注入: 装饰可以用于实现依赖注入,即将某个对象注入到类的构造函数中,使得类可以使用这个对象的功能。 总之,TypeScript装饰提供了一种灵活且强大的方式来扩展和修改类的行为,使得代码更加可重用、可扩展和易于维护。它可以应用于各种场景,提高开发效率和代码质量。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值