⭐️ 更多前端技术和知识点,搜索订阅号
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 的技术文章,只谈技术不谈八卦 ????