“开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 4 天,点击查看活动详情”
前言
ES7的与类相关的新语法,通过添加@方法名对对象进行装饰包装,返回被包装的对象。下面我将给几个实例来加深理解学习。
1.类装饰器
对于类属性或方法的装饰本质是操作其描述符,理解成是Object.defineProperty(obj, prop, descriptor)的语法糖
(Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象)
- 语法:Object.defineProperty(obj, prop, descriptor)
- obj:要在其上定义属性的对象。
- prop:要定义或修改的属性的名称。
- descriptor:将被定义或修改的属性描述符。
- 返回值:被传递给函数的对象。
实例:实现给类添加属性和方法
export function CreatePerson(isLike) {
return function(target, key, descripto) {
target.prototype.eat = () => '吃苹果'
target.isLike = true;
}
}
@CreatePerson(true)
class Person {}
let p1: any = new Person();
console.log(Person.isLike); // true
console.log(123, p1.eat()); // '吃苹果'
2. 属性装饰器
装饰属性和方法 实例:实现一个缓存的装饰器
这种缓存的思想就类似于react的useCallback或者useMemo
//采用一个Map来进行存储,这个这个缓存存在了缓存中,页面刷新后将会失效
const cacheMap = new Map();
export function EnableCache(target: any, name: string, descriptor: PropertyDescriptor) {
//获取原型对象的value
const oldValue = descriptor.value;
descriptor.value = async function(...args: any) {
//用cacheKey来判断,之前是否已经存在了,有了就替换新的;没有就直接存储
const cacheKey = name + JSON.stringify(args);
if (!cacheMap.get(cacheKey)) {
const cacheValue = Promise.resolve(oldValue.apply(this, args)).catch((_) => cacheMap.set(cacheKey, null));
cacheMap.set(cacheKey, cacheValue);
}
return cacheMap.get(cacheKey);
};
return descriptor;
}
注意:装饰器只能用于类和类的方法,不能用于函数,因为存在函数提升,如果一定要装饰函数,可以采用高阶函数的形式直接执行。
结束语
希望大家能够喜欢我的文章,我真的很用心在写,也希望通过文章认识更多志同道合的朋友。
最后伙伴们,如果喜欢我的可以给点一个小小的赞👍或者关注➕都是对我最大的支持。