Typescript中的裝飾器原理

Typescript中的裝飾器原理

一、小原理react

  由於react中的高階組件本質上是個高階函數的調用,數組

  因此高階組件的使用,咱們既能夠使用函數式方法調用,也能夠使用裝飾器。函數

  也就是說,裝飾器的本質就是一個高階函數,this

  就是利用TypeScript的弱類型特性和裝飾器特性,實現了一個增強版。spa

 


 

 

二、以一個例子來說prototype

    
//定義一個裝飾器函數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;
        }
    }
        

  編譯後:code

//第一行定義了一個_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.    }());

 

 

以上。blog

相關文章
相關標籤/搜索