装饰器
装饰器可以装饰类,将类的属性,方法修饰,将一段代码与另一端代码包装起来的方式实际上就是修饰。
普通使用
// 修饰一个类,类的属性方法都不变,但是会多出另一段代码的功能
// 装饰器函数
function log(Class) {
return (...args) => {
console.log(args); // 打印 ['嘉俊']
return new Class(...args);
};
}
@log
class Person {
constructor(name) {
this.name = name;
}
}
let z1 = new Person("嘉俊"); // 打印出传递实例类的参数
装饰器传递参数
// 多增加一个函数用来接收参数,再返回装饰器函数
// 接收 age 参数
function changeAge(age) {
// 返回装饰器函数
return (Class) => (...args) => {
console.log(args); ['16']
console.log(age); // 18
return new Class(...args);
};
}
// 装饰器传递参数
@changeAge(18)
class MyAge {
constructor(age) {
this.age = age;
}
}
let myAge = new MyAge(16);
类属性装饰器
// 用来修饰类的属性的, 参数有
// target 对象 name对象属性 descriptor修饰符
function readyOnly(attribute) {
return (target, name, descriptor) => {
descriptor.writable = name === attribute;
console.log(name);
return descriptor;
};
}
class Person2 {
constructor(name) {
this.age = name;
}
// 除了age 属性,其他属性都是只读的
@readyOnly("age")
age = 2;
@readyOnly("age")
name = "jun";
}
let y1 = new Person2("嘉俊");
y1.name = "wuhu"; // 报错,属性只读
y1.age = 18; // 可以修改
类方法修饰器
// 类方法修饰器跟属性修饰器参数一致,不过需要判断 descriptor.value 是不是一个函数
function logMethod(target, name, descriptor) {
const original = descriptor.value;
console.log(descriptor);
if (typeof original === "function") {
descriptor.value = function (...args) {
// 打印日志
console.log(`该函数传递的参数:${args}`);
// 调用方法
return original.apply(this, args);
};
}
}
class Person3 {
constructor(name) {
this.name = name;
}
@logMethod
sayHello(name) {
console.log(`你好${name},我是${this.name}`);
}
sayHello2(name) {
console.log(`你好${name},我是${this.name}`);
}
}
let y3 = new Person3("嘉俊");
y3.sayHello("侨");
y3.sayHello2("侨");