详情可查看官方网址;https://www.tslang.cn/docs/handbook/decorators.html

image.png

  1. tsc --target ES5 --experimentalDecorators

实例

简单的使用装饰器

  • app.ts ``` //简单的使用装饰器 //定义下面的装饰器所指代的函数 //taget 是被修饰的传进来的参数 function hello(target) { console.log(‘xiaochuan’); } //装饰器的声明方法 @+装饰器的名称 //下面是用装饰器去装饰一个类 @hello class xiaochuan{

}

  1. - HTML

<!DOCTYPE html>

  1. - 命令行中的执行命令与之前的也有所差异

tsc —target ES5 —experimentalDecorators app.ts

  1. - 浏览器效果图
  2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-01a8a98d2e701bae.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  3. - 总结:
  4. > 上面的示例输出了 `xiaochuan` ,但是我们并没有在代码中去调用这个方法,我们是使用了这个装饰器 `hello` 去装饰 `xiaochuan` 这个类,从而成功的打印出了上面的效果<br />
  5. ####使用装饰器工厂函数

//需求:定制一个装饰器应用到声明上 //使用装饰器工厂函数 装饰器工厂实际上就是一个函数 function color(value: string) { // 这是一个装饰器工厂 return function (target) { // 这是装饰器 // do something with “target” and “value”… } }

  1. ####多个装饰器的定义方法

//需求:定义一个函数 他的里面不止有一个装饰器 //下面示例是 定义了 f 和 g 两个装饰器去装饰 x @f @g x//单行的写法 //多行的写法 @f @g x

  1. ####多个装饰器的执行顺序

//如何知道多个装饰器的执行顺序? 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() {} }

  1. - 浏览器效果图
  2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-47e45d735dfd566a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
  3. - 总结:
  4. > 上面的执行其实是按照这样的逻辑来的:<br />
  5. f 先执行他将 g 包裹在里面 g 里面包裹的是 x f(g(x))<br />
  6. ####类装饰器

// 我们可以这样定义@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; } }

  1. - 总结:
  2. > @sealed被执行的时候,它将密封此类的构造函数和原型。(注:参见Object.seal)<br />
  3. ####方法装饰器

//下面是一个方法装饰器(@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; }

  1. @enumerable(false)
  2. greet() {
  3. return "Hello, " + this.greeting;
  4. }

} //上面类中的@enumerable(false)是一个装饰器工厂。 当装饰器 @enumerable(false)被调用时,它会修改属性描述符 descriptor 的enumerable属性。

  1. - 浏览器效果图
  2. > ![image.png](http://upload-images.jianshu.io/upload_images/9064013-678ceb66e11f73ca.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<br />
  3. ####访问器装饰器

// 我们可以通过如下函数声明来定义@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; }

  1. @configurable(false)
  2. get x() { return this._x; }
  3. @configurable(false)
  4. get y() { return this._y; }

}

  1. ####属性装饰器

function configurable(value: boolean) { return function (target: any, propertyKey: string) { console.log(‘属性:’,value); }; } class Hello{ @configurable(false)//这里在执行值会直接在控制台输出一个 false name:string; }

  1. ####参数装饰器

function require(value: boolean) { return function (target: any, propertyKey: string,index:number) {//index 是增加的索引参数 console.log(‘参数:’,value); }; } class Hello{ xiaochuan(@require(false) age:number){

  1. }

}

```