一、小原理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