美文网首页
对Descriptor的理解

对Descriptor的理解

作者: 笑笑料料 | 来源:发表于2018-08-28 21:43 被阅读0次

    修饰类

    target参数指的是,构造函数(类)Person,而不是实例。如果想对实例进行修饰,可以通过target.prototype对实例的属性进行修饰

    const init = (target) => {
      target.nickName = 'person_name'
      target.prototype.nickName = 'kitty'
    }
    
    @init
    class Person {
      nickName = 'native_name'
    }
    
    const cat = new Person()
    
    console.log('Person', Person.nickName)  // 'Person person_name'
    console.log('instance', cat.nickName) // 'instance native_name'
    

    修饰方法

    const log = (target, name, descriptor) => {
    // 这里的this为undefined
      const oldAdd = descriptor.value
    
    descriptor.value = function(){
        console.log(`传入实例方法add的参数${arguments}`)
        console.log(`实例中的age属性:${this.age}`)
        return oldAdd.apply(this, arguments)
      }
    
      return descriptor
    }
    
    class Math {
      @log
      add(a, b){
        return a + b
      }
    }
    
    var math = new Math()
    const value = math.add(3, 6)
    console.log(`value is equal to ${value}`)
    

    结果为:

    传入实例方法add的参数[object Arguments]
    实例中的age属性:10
    value is equal to 9
    

    其中

    descriptor.value = function(){
        console.log(`传入实例方法add的参数${arguments}`)
        console.log(`实例中的age属性:${this.age}`)
        return oldAdd.apply(this, arguments)
      }
    

    this作用域为指向的是Math的实例math;当然this可以用target代替。

    半透明的装饰模式(利用修饰类去修饰方法)

    const addFly = (canFly) => {
      return (target) => {
        const extra = canFly ? '添加飞行技能' : ''
        const old_toString = target.prototype.toString
    
        target.prototype.toString = (...args) => {
          // 这里的target只是指Man类,不能指向实例, 应该用targey.prototype指向实例
          return old_toString.apply(target.prototype, args) + extra
        }
      }
    }
    
    
    @addFly(true)
    class Man{
      constructor(def = 2,atk = 3,hp = 3){
        this.init(def,atk,hp)
      }
      @decorateArmour
      @decorateLight
      init(def,atk,hp){
        this.def = def // 防御值
        this.atk = atk  // 攻击力
        this.hp = hp // 血量
      }
      toString(){
        return `防御力:${this.def},攻击力:${this.atk},血量:${this.hp}`
      }
    }
    
    

    通过引用函数的方式改变某个函数

    在不改变函数源代码的情况下,能给函数增加功能,符合开放-封闭原则

    let con = () => {
     // 也可直接用function关键字来声明
      console.log('old con')
    }
    
    const _con = con
    
    con = () => {
      _con()
      console.log('new con')
    }
    con()
    

    相关文章

      网友评论

          本文标题:对Descriptor的理解

          本文链接:https://www.haomeiwen.com/subject/glkcwftx.html