修饰器模式

2019-07-30 10:08:18 浏览数 (2)

不会改变原有的对象,而是在其基础上进行拓展。

实现原理

  • 创建一个 A 类
  • A 类中的属性和方法使用 ES7 中的修饰器语法对类和类的属性增加功能

实现代码

ts 修饰器语法

如下是 ts 官方文档的例子:

https://zhongsp.gitbooks.io/typescript-handbook/doc/handbook/Decorators.html

代码语言:javascript复制
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() {}
}

函数式

代码语言:javascript复制
let obj = {
  lname: "young",
  fname: "oliver",
  gender: "male",
  getInfo() {
    return "get user infomation";
  }
};

// 这时需要添加一些方法,可以使用修饰器模式
// 这是需要添加的方法
function getGender() {
  console.log(this.gender);
}
function getFullName() {
  console.log(`${this.fname} ${this.lname}`);
}

obj.getInfo = function() {
  let getInfo = obj.getInfo;
  return function() {
    getInfo();
    getGender.call(obj); // 需要手动绑定 this
    getFullName.call(obj); // 需要手动绑定 this
  };
};

obj.getInfo()();

AOP 装饰函数

代码语言:javascript复制
// 前置代码
Function.prototype.before = function(fn) {
  const self = this
  return function() {
    fn.apply(new(self), arguments)
    return self.apply(new(self), arguments)
  }
}

// 后置代码
Function.prototype.after = function(fn) {
  const self = this
  return function() {
    self.apply(new(self), arguments)
    return fn.apply(new(self), arguments)
  }
}
代码语言:javascript复制
const wear1 = function() {
  console.log('穿上第一件衣服')
}

const wear2 = function() {
  console.log('穿上第二件衣服')
}

const wear3 = function() {
  console.log('穿上第三件衣服')
}

const wear = wear1.after(wear2).after(wear3)
wear()

// 穿上第一件衣服
// 穿上第二件衣服
// 穿上第三件衣服

缺点是在 Function 的原型链上增加了 before、after 导致原生函数被污染

改成以下:

代码语言:javascript复制
const after = function(fn, afterFn) {
  return function() {
    fn.apply(this, arguments)
    afterFn.apply(this, arguments)
  }
}

const wear = after(after(wear1, wear2), wear3)
wear()

0 人点赞