前言
装饰器是 JavaScript 中一个非常强大的特性,它允许你在不修改原有函数或类的情况下,为它们添加新的功能。
上代码!
(●'◡'●)
正文
1. 函数装饰器
函数装饰器可以用来修改函数的行为。
// 定义一个装饰器函数
function logDecorator(targetFn) {
// 返回一个新的函数,这个新函数会替换原来的函数
return function(...args) {
// 注意:此处的【...args】其实就是targetFn的入参!!
console.log(`调用了函数 ${targetFn.name},参数是:`, args);
// 调用原始的函数
return targetFn(...args);
};
}
// 使用装饰器
const add = logDecorator(function(a, b) {
return a + b;
});
// 调用装饰后的函数
console.log(add(3, 4)); // 输出:调用了函数 ƒ,参数是: [3, 4],然后输出 7
说明:
logDecorator是一个装饰器函数,它接收一个函数targetFn作为参数。- 装饰器返回一个新的函数,这个新函数在调用时会先打印日志,然后调用原始的
targetFn。 - 这个虽然不像装饰器,但真的是装饰器
2. 类装饰器
类装饰器可以用来修改类的行为。
// 定义一个类装饰器
function logClass(targetClass) {
// 返回一个新的类,这个新类会替换原来的类
return class extends targetClass {
constructor(...args) {
console.log(`创建了一个 ${targetClass.name} 实例,参数是:`, args);
super(...args);
}
};
}
// 使用装饰器
@logClass
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
}
// 创建实例
const person = new Person('Alice', 25);
// 输出:创建了一个 Person 实例,参数是: [ 'Alice', 25 ]
说明:
@logClass是一个类装饰器,它接收一个类targetClass作为参数。- 装饰器返回一个新的类,这个新类在创建实例时会先打印日志,然后调用原始类的构造函数。
3. 方法装饰器
方法装饰器可以用来修改类中的方法。
// 定义一个方法装饰器
function logMethod(target, propertyKey, descriptor) {
// 获取原始的方法
const originalMethod = descriptor.value;
// 替换原始的方法
descriptor.value = function(...args) {
console.log(`调用了方法 ${propertyKey},参数是:`, args);
// 调用原始的方法
return originalMethod.apply(this, args);
};
}
// 使用装饰器
class Calculator {
@logMethod
add(a, b) {
return a + b;
}
}
// 创建实例并调用方法
const calc = new Calculator();
console.log(calc.add(5, 6)); // 输出:调用了方法 add,参数是: [5, 6],然后输出 11
说明:
@logMethod是一个方法装饰器,它接收三个参数:target:类的原型或类本身。propertyKey:方法的名称。descriptor:方法的描述符,包含原始方法的引用。
- 装饰器通过修改
descriptor.value来替换原始方法。
4. 属性装饰器
属性装饰器可以用来修改类中的属性。
// 定义一个属性装饰器
function logProperty(target, propertyKey) {
let value = target[propertyKey];
// 替换属性的 getter 和 setter
Object.defineProperty(target, propertyKey, {
get: function() {
console.log(`获取属性 ${propertyKey}`);
return value;
},
set: function(newValue) {
console.log(`设置属性 ${propertyKey} 为 ${newValue}`);
value = newValue;
}
});
}
// 使用装饰器
class User {
@logProperty
name = 'Alice';
}
// 创建实例并操作属性
const user = new User();
console.log(user.name); // 输出:获取属性 name,然后输出 Alice
user.name = 'Bob'; // 输出:设置属性 name 为 Bob
console.log(user.name); // 输出:获取属性 name,然后输出 Bob
说明:
@logProperty是一个属性装饰器,它接收两个参数:target:类的原型或类本身。propertyKey:属性的名称。
- 装饰器通过
Object.defineProperty修改属性的 getter 和 setter。
最后
建议在项目中使用起来
下次见(●'◡'●)!