Typescript中的装饰器原理

Typescript中的装饰器原理

1、小原理

  因为react中的高阶组件本质上是个高阶函数的调用,

  所以高阶组件的使用,我们既可以使用函数式方法调用,也可以使用装饰器。

  也就是说,装饰器的本质就是一个高阶函数,

  就是利用TypeScript的弱类型特性和装饰器特性,实现了一个加强版。


2、以一个例子来讲

//定义一个装饰器函数decTest

    function decTest(constructor: Function) {
console.log(constructor("hello!"));
} //在类Greeter上安装decTest装饰器 @decTest class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
console.log("in constructor:",message);
}
greet() {
return "Hello, " + this.greeting;
}
}

  编译后:

//第一行定义了一个_decarate函数,这个函数会处理类装饰器的功能

//第18行可以看出,调用_decorate函数时只给了两个参数,
//一个是数组,其中包含多个类装饰器,这里只使用了一个装饰器
//另一个是Greeter类的构造函数Greeter()
//调用__decorate函数时decorators为一个装饰器数组;
//target为构造函数Greeter(),
//key和desc均未使用,值为undefined。
//这里的__decorate函数为各种装饰器的通用代码,
//在方法装饰器中key和desc均有使用。 1. var __decorate = (this && this._decorate) || function (decorators, target, key, desc) { //第2行参数数量在类装饰器中为2,显然小于3。 2. var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; //第3行指出如果系统支持反射,
//则直接使用Reflect.decorate(decorators,target, key, desc)方法。
//否则自行定义实现装饰器机制的代码。 3. if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4. else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5. return c > 3 && r && Object.defineProperty(target, key, r), r;
6. };
7. function decTest(constructor) {
8. console.log(constructor("hello!"));
9. } //定义了一个函数,从第22行可以看出,这个函数是自调用的 10. var Greeter = (function () {
11. function Greeter(message) {
12. this.greeting = message;
13. console.log("in constructor:", message);
14. }
15. Greeter.prototype.greet = function () {
16. return "Hello, " + this.greeting;
17. }; //18行的时候函数调用了_decorate函数 18. Greeter = __decorate([
19. decTest
20. ], Greeter);
21. return Greeter;
22. }());

  简化:

1.    var __decorate = function (decorators, target, key, desc) {
2. r = target; //可以看出第三行实现了装饰器的堆叠
//堆叠的规则是先处理后面的,
//再处理前面的 3. for (var i = decorators.length - 1; i >= 0; i--)
4. if (d = decorators[i]) r = d(r);
5. return r;
6. };
7.
8. function decTest(constructor) {
9. console.log(constructor("hello!"));
10. } //这个方法最后返回一个Greeter,改造后的Greeter 11. var Greeter = (function () {
12. function Greeter(message) {
13. this.greeting = message;
14. console.log("in constructor:", message);
15. }
16. Greeter.prototype.greet = function () {
17. return "Hello, " + this.greeting;
18. }; //第19行实际上就是通过类装饰器函数修改了Greeter类的构造函数Greeter(message)的行为,
//从而修改了对象的特性,
//比如增加接口,注入类成员……等等。 19. Greeter = __decorate([
20. decTest
21. ], Greeter);
22. return Greeter;
23. }());

以上。

上一篇:ServletConfig使用


下一篇:linux - CentaOS 7 - 安装kafka