- Decorator 基本知识
在很多框架和库中看到它的身影,尤其是 React 和 Redux,还有 mobx 中,那什么是装饰器呢。
修饰器(Decorator)是一个函数,用来修改类的行为。不是很理解这种抽象概念,还是看代码讲解实际些。
//定义一个函数,也就是定义一个 Decorator,target 参数就是传进来的 Class。
//这里是为类添加了一个静态属性
function addAge(target) {
target.age = 2;
}
//在 Decorator 后面跟着 Class,Decorator 是函数的话,怎么不是 addAge(MyGeekjcProject)这样写呢?
//我只能这样理解:因为语法就这样,只要 Decorator 后面是 Class,默认就已经把 Class 当成参数隐形传进 Decorator 了(就是所谓的语法糖)。
@addAge
class MyGeekjcProject {}
console.log(MyGeekjcProject.age) // 2
1.1 传参修饰类
但上面这样只传了一个 Class 作为参数不够灵活怎么办?
我们可以在外层套一个函数,只要最后返回的是一个 Decorator 即可,管你套多少个函数传多少个参数都无所谓。
function addAge(age) {
return function(target) {
target.age = age;
}
}
//注意这里,隐形传入了 Class,语法类似于 addAge(2)(MyGeekjcProject)
@testable(2)
class MyGeekjcProject {}
MyGeekjcProject.age // 2
@addAge(3)
class MyGeekjcProject {}
MyGeekjcProject.age // 3
1.2 修饰类的属性
下面是修改类的 prototype 对象
function description(target) {
target.prototype.url = ‘https://www.geekjc.com';
}
@description
class MyGeekjcProject {}
let geekjc = new MyGeekjcProject();
geekjc.url // https://www.geekjc.com
概念大概理解了,修饰器不仅可以修饰类,还可以修饰类的属性
//假如修饰类的属性则传入三个参数,对应 Object.defineProperty()里三个参数,具体不细说
//target 为目标对象,对应为 Class 的实例
//name 为所要修饰的属性名,这里就是修饰器紧跟其后的 name 属性
//descriptor 为该属性的描述对象
//这里的 Decorator 作用是使 name 属性不可写,并返回修改后的 descriptor
function readonly(target, name, descriptor){
descriptor.writable = false;
return descriptor;
}
class Person {
@readonly
name() { return ${this.first} ${this.last} }
}
关于 Object.defineProperty()可以看文章学习 Object.defineProperty
再看一个复杂的例子
//定义一个 Class 并在其 add 上使用了修饰器
class Math {
@log
add(a, b) {
return a + b;
}
}
//定义一个修饰器
function log(target, name, descriptor) {
//这里是缓存旧的方法,也就是上面那个 add()原始方法
var oldValue = descriptor.value;
//这里修改了方法,使其作用变成一个打印函数
//最后依旧返回旧的方法,真是巧妙
descriptor.value = function() {
console.log(Calling "${name}" with, arguments);
return oldValue.apply(null, arguments);
};
return descriptor;
}
const math = new Math();
math.add(2, 4);
看完上面的代码就知道 decorator 有什么用了,修饰器不仅可以修饰类的行为,还可以修饰类的属性。
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:ll
链接:https://www.geekjc.com/post/5bd178618721cf095290a7f4
来源:极客教程

