10-TypeScirpt-装饰器-混入

2020-10-05  本文已影响0人  低头看云

装饰器

1.什么是装饰器?

  1. 装饰器基本格式
    2.1普通装饰器
    2.2装饰器工厂
    2.3装饰器组合

3.如何在TS中使用装饰器?
在TS中装饰器也是一项实验性的特性, 所以要使用装饰器需要手动打开相关配置
修改配置文件 experimentalDecorators


  function test(target) {
    console.log('test')
    console.log('target', target)
  }
  // 如果一个函数返回一个回调函数, 如果这个函数作为装饰器来使用
  // 那么这个函数就是装饰器工厂
  function test1() {
    console.log('test1 out')
    return (target) => {
      console.log('target', target)
      console.log('test1 in')
    }
  }

  function test2(target) {
    console.log('test2')
  }

  function test3() {
    console.log('test3  out')
    return (target) => {
      console.log('test3 in')
    }
  }

  // 执行顺序
  // 结合起来使用, 回想从上至下执行所有的装饰器工厂, 拿到所有真正的装饰器
  // 然后再从下至上执行所有的装饰器
  // test1 out /  test3 out / test3 in / test2 / test1 in / test

  @test
  @test1()
  @test2
  @test3()
  class Person {}

类装饰器

  function demo<T extends { new (...args: any[]) }>(target: T) {
    return class extends target {
      name: string = 'css'
      age: number = 18
    }
  }

  @demo
  class Person1 {}

  let p1 = new Person1()
  console.log(p1)

defineProperty

  let obj = { age: 18 }

  Object.defineProperty(obj, 'name', {
    value: 'css',
  })

  console.log('obj', obj) // {age: 18, name: "css"}
  let obj1 = { age: 18 }

  Object.defineProperty(obj1, 'age', {
    value: 22,
  })

  console.log('obj1', obj1) // {age: 22}
  let obj2 = { age: 18 }
  Object.defineProperty(obj2, 'age', {
    writable: false,
    //   writable: true,
  })

  obj2.age = 111
  console.log('obj2', obj2) // {age: 18}
  let obj3 = { age: 14, name: 'js' }

  Object.defineProperty(obj3, 'name', {
    enumerable: false,
  })
  for (let key in obj3) {
    console.log(key) // age
  }
  let obj4 = { age: 18, name: 'lnj' }
  Object.defineProperty(obj4, 'name', {
    enumerable: false,
    configurable: false,
  })
  Object.defineProperty(obj4, 'name', {
    enumerable: true,
    configurable: false,
  })
  for (let key in obj4) {
    console.log(key)
  }

方法装饰器

  function test(
    target: any,
    propertKe: string,
    descriptor: PropertyDescriptor
  ) {
    console.log('descriptor', descriptor)
    console.log('propertKe', propertKe)
    console.log('target', target)
   
    // configurable?: boolean;
    // enumerable?: boolean;
    // value?: any;
    // writable?: boolean;

    //   descriptor.enumerable = false
    descriptor.value = () => {
      console.log('323232332')
    }
  }

  class Person {
    // @test
    sayName(): void {
      console.log('my name is css')
    }
    @test
    sayAge(): void {
      console.log('my age is 18')
    }
    // @test
    static say(): void {
      console.log('say hello world')
    }
  }

  let p = new Person()

  p.sayAge()

访问器装饰器

  function test(
    target: any,
    propertyKey: string,
    descriptor: PropertyDescriptor
  ) {
    // console.log(target);
    // console.log(propertyKey);
    // console.log(descriptor);
    descriptor.set = (value: string) => {
      console.log('value', value)
      target.myName = value
    }
    descriptor.get = (): string => {
      return target.myName
    }
  }

  class Person {
    private _name: string
    constructor(name: string) {
      this._name = name
    }
    @test
    get name(): string {
      return this._name
    }
    set name(value: string) {
      this._name = value
    }
  }

  let p = new Person('css')
  p.name = 'react'

  console.log(p.name)

  console.log('p', p)
  

参数装饰器

  function test(target: any, proptyName: string, index: number) {
    console.log(target)
    console.log(proptyName)
    console.log(index)
  }
  class Person {
    say(age: number, @test name: string): void {}
  }

属性装饰器

  function test(target: any, proptyName: string) {
    console.log(target)
    console.log(proptyName)
    target[proptyName] = 'css'
  }
  class Person {
    @test
    static age: number
    //   @test
    name?: string
  }
  let p = new Person()
  console.log(p)
  console.log(Person.age)

混入

let obj1 = {name:'lnj'};
let obj2 = {age:34};
Object.assign(obj1, obj2);
console.log(obj1);
console.log(obj2);
 class Dog {
    name: string = 'wc'
    say(): void {
      console.log('wang wang')
    }
  }
  class Cat {
    age: number = 3
    run(): void {
      console.log('run run')
    }
  }
  // 注意点: 一次只能继承一个类
  // class Animal extends Dog, Cat{
  //
  // }
  class Animal implements Dog, Cat {
    name: string
    age: number
    say: () => void
    run: () => void
  }
  function myMixin(target: any, from: any[]) {
    from.forEach((fromItem) => {
      Object.getOwnPropertyNames(fromItem.prototype).forEach((name) => {
        target.prototype[name] = fromItem.prototype[name]
      })
    })
  }
  myMixin(Animal, [Dog, Cat])
  let a = new Animal()
  console.log(a)
  a.say()
  a.run()
  // console.log(a.name);
  // console.log(a.age);
 
上一篇 下一篇

猜你喜欢

热点阅读