不会改变原有的对象,而是在其基础上进行拓展。
实现原理
- 创建一个 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()