Skip to content

es7

修饰器

※ 初步印象:用来在初始化类时进行一些公共操作

@Student({course: "angular3"})
class A {…}

function Student(config) {
    return function (target) {
        Object.defineProperty(target.prototype, 'course', {value: () => config.course})
        //也可写成: target.prototype.course = '…'; return target;
    }
}

若无需config的话那么既不用给Student传参 底下的实现function中只需里面那层就好了

function Student(target) {Object.defineProperty(target.prototype, 'course', {value: () => config.course})}

※ 进阶

①纯粹的装饰模式<于类的属性上修改> 蓝色部分。需要返回的是属性的描述符descriptor。

②半透明的装饰模式<于类上整体修改属性> 红色部分。需要返回的是target。https://jsfiddle.net/hhqgs8v6/1/

function decorateArmour(target, key, descriptor) {
  //这儿target是类的prototype
//先将原有属性提取出来 
 const method = descriptor.value;
  //纯粹的装饰器
  let moreDef = 100;
  descriptor.value = (...args)=>{
    //这里对入参进行修改
    args[0] += moreDef;
    return method.apply(target, args);
  }
  return descriptor;
}

//半透明的装饰器 +属性 类似于适配器
function addSpeed(target) {
   //这儿target是类本身
const method = target.prototype.toString;
 target.prototype.toString = (...args) => {
      return method.apply(target.prototype, args) + '加成!'
    }
原来以上不对<因为target.prototype上的def,atk这些都是undefined的呀> 需改成
target.prototype. toString = function(…args){
    return method.apply(this, args)+'加成'
}   
return target;
}

@addSpeed
class Man{
  constructor(def = 2,atk = 3,hp = 3){
    this.init(def,atk,hp);
  }

  @decorateArmour
  init(def,atk,hp){
    this.def = def; // 防御值
    this.atk = atk;  // 攻击力
    this.hp = hp;  // 血量
  }
  toString(){
    return `防御力:${this.def},攻击力:${this.atk},血量:${this.hp}`;
  }
}

var tony = new Man();

※ es5实现的思路

其实还是类的继承关系,或是添加额外的职责