黑马程序员技术交流社区

标题: 【广州前端首发】TypeScript核心课程笔记(五) [打印本页]

作者: AreYouGlad    时间: 2017-12-15 16:37
标题: 【广州前端首发】TypeScript核心课程笔记(五)
本帖最后由 AreYouGlad 于 2017-12-20 11:53 编辑

查看更多精彩前端资源


装饰器
简介
编译说明
使用说明初探装饰器

装饰器语法
[AppleScript] 纯文本查看 复制代码
function decoratorFn(...arg: any[]) {
                console.log('我执行了, 并且我自动收到了下面的东西!');
                console.log(arg);
}

// 写法1: 在类的前一行使用装饰器
@decoratorFn
class Test {}

// 写法2: 在类前面的使用装饰器
@decoratorFn class Test2 {}

装饰属性与方法
[AppleScript] 纯文本查看 复制代码
function decoratorFn(...arg: any[]) {
                console.log('我执行了, 并且我自动收到了下面的东西!');
                console.log(arg);
}

class Test {
    @decoratorFn
    static staticProp: string = '静态属性';

    @decoratorFn
    static staticFn(): void {
            console.log('静态方法');
    }

    @decoratorFn
    instanceProp: string = '实例属性';

    @decoratorFn
    instanceFn(): void {
            console.log('实例方法');
    }
}

装饰器作用
装饰类
[AppleScript] 纯文本查看 复制代码
// 增强类的静态成员
function addFeature(target: any): void {
  let newFeature = ['拉', '撒', '睡'];
  if(target.feature) {
          target.feature.push(...newFeature);
  }
}

@addFeature
class Person {
        static feature: string[] = ['吃', '喝'];
}

@addFeature
class Cat {
        static feature: string[] = ['吃', '喝'];
}

// 测试
console.log(Person.feature);    // ['吃', '喝', '拉', '撒', '睡']
console.log(Cat.feature);         // ['吃', '喝', '拉', '撒', '睡']

装饰器优点
[AppleScript] 纯文本查看 复制代码
function feature(target: any): void {
  target.feature = ['吃', '喝', '拉', '撒', '睡'];
}

class Person {}
class Dog {}

// 实现了和装饰器同样的效果, 但是写起来明显不如装饰器语法来的简单
// 同时语义上无法直观的看出调用feature方法是为了增强类, 谁知道feature内部干了什么
feature(Person);
feature(Dog);

装饰方法
[AppleScript] 纯文本查看 复制代码
function executeTime(target: any, name: string, msg: any): void {
  // 缓存旧方法
  let oldFn = msg.value;

  // 赋值新方法, 新方法对旧方法进行了功能扩展
  msg.value = function(...arg: any[]) {
    let date = Date.now();
    oldFn.call(this, ...arg);
          console.log(`执行了: ${Date.now() - date} 毫秒`);
  }
}

class Person {

        @executeTime
  static getTotal(): void {
    console.log('70亿');
  }

  @executeTime
  study(time: number): void {
          for(let i =0; i < time; i++) {
                  console.log('学习');
          }
  }
}

// 测试
new Person().study(1000);
Person.getTotal()

装饰属性
[AppleScript] 纯文本查看 复制代码
function getSet(...arg: any[]): void {
    let classOrPrototype = arg[0];  // 类或原型
    let propName = arg[1];           // 属性名称

    // 根据属性名称添加对应的set方法
    classOrPrototype[propName + 'Set'] = function(val: any): void {
        this[propName] = val;
    }

    // 根据属性名称添加对应的get方法
    classOrPrototype[propName + 'Get'] = function(): any {
        return this[propName];
    }
}

class Person {
    @getSet
    name: string = '匿名';

    @getSet
    static total: number = 0;
}

// 测试
Person.totalSet(100);
Person.totalGet();

let fang: Person = new Person();
fang.nameSet('芳芳');
fang.nameGet();

装饰器工厂 - 可传参的装饰器
语法
[AppleScript] 纯文本查看 复制代码
// 外层的函数可收到用户传递的参数
function test(param: string): any {
  console.log(param);

  // 内层函数可收到装饰器自动传递的参数, 说白了就是以前的装饰器函数
        return function(target: any): void {
          console.log(target);
        }
}

// 这里的装饰器语法相比以前多了小括号调用与传参
@test('可以传参?')
class Person {}
// 装饰器工厂内部返回一个函数, 内部的函数就是我们之前写的装饰器函数
function getZhuangshiqi(a: number) {

    // 这个装饰器函数可以自动接收到一些值, 因为我们这个案例装饰了类, 那么就应该得到一个类
    return function(target: any) {

        // 现在这个装饰器函数即可以使用用户传过来的参数, 也可以使用自动传过来的参数
        console.log(a);
        console.log(target);
    }
}

// 用户现在可以调用传参
@getZhuangshiqi(123)
class Person{}

使用范例
[AppleScript] 纯文本查看 复制代码
function feature(level: string): any {
        return function(target: any): void {
          // 高等生物
          if(level === '高等') {
            target.feature.push('玩', '乐');
          }
          // 低等生物
          else if(level === '低等') {
            target.feature.push('拉', '撒');
          }
        }
}

@feature('高等')
class Person {
        static feature: string[] = ['吃', '喝'];
}

@feature('低等')
class Dog {
        static feature: string[] = ['吃', '喝'];
}

补充

[AppleScript] 纯文本查看 复制代码
function decorator1(...arg: any[]) {
        console.log('装饰器1');
}

function decorator2(...arg: any[]) {
        console.log('装饰器2');
}

function decorator3(...arg: any[]) {
        console.log('装饰器3');
}

@decorator1
@decorator2
@decorator3
class Person {}







作者: AreYouGlad    时间: 2017-12-15 16:37





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2