es6 装饰器
裝飾器是一種函數,寫成@ + 函數名。它可以放在類和類方法的定義前面。用來注釋或修改類和類方法
1.類的裝飾
裝飾器對類的行為的改變,是代碼編譯時發生的,而不是在運行時。這意味著,裝飾器能在編譯階段運行代碼。也就是說,裝飾器本質就是編譯時執行的函數。
類裝飾器函數target參數指的是類本身
@testable class MyClass {};//@testable裝飾器修改了MyClass這個類的行為,為它添加了靜態屬性isTestable function testable(target) {//target是MyClass類本身target.isTestable = true; // 為類添加靜態屬性target.prototype.grade = 3; // 為類添加實例屬性 }console.log(MyClass.isTestable); // true具體運行參考:https://blog.csdn.net/qq_34035425/article/details/120385667
裝飾器的行為
@decorator class A {}// 等同于class A {} A = decorator(A) || A;裝飾器是一個對類進行處理的函數。裝飾器函數的第一個參數,就是所要裝飾的目標類。
裝飾器添加參數
如果覺得一個參數不夠用,可以在裝飾器外面再封裝一層函數
//定義裝飾器的外層函數 function testable(isTestable) {//返回一個裝飾器函數return function(target) {target.prototype.isTestable = true;} }@testable(true) class MyTestableClass {} MyTestableClass.isTestable // true2.方法裝飾器
裝飾器不僅可以裝飾類,還可以裝飾類的屬性。
定義 readonly裝飾器:第一個參數是類的原型對象;第二個參數是所要修飾的屬性名;第三個參數是該屬性的描述對象。
如果一個方法有多個裝飾器,會像剝洋蔥一樣,先從外到內進入,然后由內向外執行
//定義裝飾器的外層函數 function dec(id){console.log('evaluated', id);//返回一個裝飾器函數return (target, property, descriptor) => console.log('executed', id);}class Example {@dec(1)@dec(2)method(){} } // evaluated 1 // evaluated 2 // executed 2 // executed 1外層裝飾器@dec(1)先進入,但是內層裝飾器@dec(2)先執行
為什么裝飾器不能用于函數
裝飾器只能用于類和類的方法,不能用于函數,因為存在函數提升。
由于存在函數提升,使得修飾器不能用于函數。類是不會提升的,所以就沒有這方面的問題。
我們意圖是執行后counter等于 1,但是實際上結果是counter等于 0。因為函數提升,使得實際執行的代碼是下面這樣。
var counter; var add;@add function foo() { }counter = 0; add = function () {counter++; };總結
- 上一篇: ts-node 直接运行ts文件
- 下一篇: git 推送本地分支到远程分支 git