乐趣区

修饰器模式

⭐️ 更多前端技术和知识点,搜索订阅号 JS 菌 订阅

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

实现原理

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

实现代码

ts 修饰器语法

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

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

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() {}
}

函数式

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 装饰函数

// 前置代码
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)
  }
}
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 导致原生函数被污染

改成以下:

const after = function(fn, afterFn) {return function() {fn.apply(this, arguments)
    afterFn.apply(this, arguments)
  }
}

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

请关注我的订阅号,不定期推送有关 JS 的技术文章,只谈技术不谈八卦 ????

退出移动版