詳情可查看官方網址;https://www.tslang.cn/docs/handbook/decorators.html
image.png
tsc --target ES5 --experimentalDecorators
實例
簡單的使用裝飾器
- app.ts
//簡單的使用裝飾器
//定義下面的裝飾器所指代的函數
//taget 是被修飾的傳進來的參數
function hello(target) {
console.log('xiaochuan');
}
//裝飾器的聲明方法 @+裝飾器的名稱
//下面是用裝飾器去裝飾一個類
@hello
class xiaochuan{
}
- HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TypeScript 裝飾器</title>
</head>
<body>
<script type="text/javascript" src="app.js"></script>
</body>
</html>
- 命令行中的執行命令與之前的也有所差異
tsc --target ES5 --experimentalDecorators app.ts
- 瀏覽器效果圖
image.png
- 總結:
上面的示例輸出了
xiaochuan
,但是我們并沒有在代碼中去調用這個方法,我們是使用了這個裝飾器hello
去裝飾xiaochuan
這個類,從而成功的打印出了上面的效果
使用裝飾器工廠函數
//需求:定制一個裝飾器應用到聲明上
//使用裝飾器工廠函數 裝飾器工廠實際上就是一個函數
function color(value: string) { // 這是一個裝飾器工廠
return function (target) { // 這是裝飾器
// do something with "target" and "value"...
}
}
多個裝飾器的定義方法
//需求:定義一個函數 他的里面不止有一個裝飾器
//下面示例是 定義了 f 和 g 兩個裝飾器去裝飾 x
@f @g x//單行的寫法
//多行的寫法
@f
@g
x
多個裝飾器的執行順序
//如何知道多個裝飾器的執行順序?
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() {}
}
- 瀏覽器效果圖
image.png
- 總結:
上面的執行其實是按照這樣的邏輯來的:
f 先執行他將 g 包裹在里面 g 里面包裹的是 x f(g(x))
類裝飾器
// 我們可以這樣定義@sealed裝飾器:
function sealed(constructor: Function) {
Object.seal(constructor);
Object.seal(constructor.prototype);
}
// 下面是使用類裝飾器(@sealed)的例子,應用在Greeter類:
@sealed
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
greet() {
return "Hello, " + this.greeting;
}
}
- 總結:
當@sealed被執行的時候,它將密封此類的構造函數和原型。(注:參見Object.seal)
方法裝飾器
//下面是一個方法裝飾器(@enumerable)的例子
//我們可以用下面的函數聲明來定義@enumerable裝飾器:
function enumerable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {//PropertyDescriptor 是屬性描述器
descriptor.enumerable = value;
console.log(descriptor.enumerable);
};
}
class Greeter {
greeting: string;
constructor(message: string) {
this.greeting = message;
}
@enumerable(false)
greet() {
return "Hello, " + this.greeting;
}
}
//上面類中的@enumerable(false)是一個裝飾器工廠。 當裝飾器 @enumerable(false)被調用時,它會修改屬性描述符 descriptor 的enumerable屬性。
- 瀏覽器效果圖
image.png
訪問器裝飾器
// 我們可以通過如下函數聲明來定義@configurable裝飾器:
function configurable(value: boolean) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
descriptor.configurable = value;
};
}
// 下面是使用了訪問器裝飾器(@configurable)的例子,應用于Point類的成員上:
class Point {
private _x: number;
private _y: number;
constructor(x: number, y: number) {
this._x = x;
this._y = y;
}
@configurable(false)
get x() { return this._x; }
@configurable(false)
get y() { return this._y; }
}
屬性裝飾器
function configurable(value: boolean) {
return function (target: any, propertyKey: string) {
console.log('屬性:',value);
};
}
class Hello{
@configurable(false)//這里在執行值會直接在控制臺輸出一個 false
name:string;
}
參數裝飾器
function require(value: boolean) {
return function (target: any, propertyKey: string,index:number) {//index 是增加的索引參數
console.log('參數:',value);
};
}
class Hello{
xiaochuan(@require(false) age:number){
}
}