概念
装饰器其实就是一个函数,它作用于类本身、类的原型属性/方法、类的实例属性/方法,在编译阶段注入自定义逻辑从而在不改变代码结构的前提下对类进行功能强化
装饰类本身
定义装饰器
// 这里接收的参数target是要装饰的类本身
function deco(target) {
target.prototype.sayHello = () => console.log('Hello');
// 或者return一个新类也可以
}
使用它
import deco from 'src/deco'
// 装饰器的用法:加@
@deco
class Person {}
// 编译阶段装饰器已经把sayHello注入到Person的原型对象上了
const someone = new Person();
someone.sayHello(); // Hello
装饰类的原型属性/方法
定义装饰器
// target - 类的原型对象
// name - 被装饰的属性名
// descriptor - 被装饰的属性的描述符
function deco(target, name, descriptor) {
const func = descriptor.value;
descriptor.value = function(...args) {
func.apply(this, args);
console.log('world');
}
// 或者return一个新descriptor也可以
}
使用它
import deco from 'src/deco'
import anotherDeco from 'src/anotherDeco'
class Person {
@deco
sayHello() {
console.log('hello');
}
@anotherDeco
get age() {
return 18;
}
}
// 编译阶段装饰器已经注入到sayHello中了
const someone = new Person();
someone.sayHello(); // hello\r\nworld
装饰类的实例属性/方法
定义装饰器
// target - 类的原型对象
// name - 被装饰的属性名
// descriptor - 被装饰的属性的描述符
function (target, name, descriptor){
// 以此可以获取实例化的时候此属性的默认值
let v = descriptor.initializer && descriptor.initializer.call(this);
// 返回一个新的描述对象,或者直接修改 descriptor 也可以
return {
enumerable: true,
configurable: true,
get: function() {
return v;
},
set: function(c) {
v = c;
}
}
}
使用它
import deco from 'src/deco'
import anotherDeco from 'src/anotherDeco'
class Person {
@deco
age = 18;
@anotherDeco
sayHello = () => console.log('hello');
}
// 编译阶段装饰器已经注入到sayHello中了
const someone = new Person();
someone.age; // 18
高阶装饰器
其实这个名字是我自己起的,我这里所说的高阶装饰器指的是一个返回装饰器函数的函数
const hyperDeco = age =>
target => target.prototype.getAge = () => age
@hyperDeco(18) // 先执行hyperDeco返回一个装饰器,再装饰Person类
class Person {}
const someone = new Person();
someone.getAge(); // 18;
知识点
-
装饰器在编译阶段执行
-
多个装饰器会像剥洋葱一样,先从外到内进入,然后由内向外执行。
function dec(id){
console.log('evaluated', id);
return (target, property, descriptor) => console.log('executed', id);
}
class Example {
@dec(1)
@dec(2)
method(){}
}
// evaluated 1
// evaluated 2
// executed 2
// executed 1
- 如果要装饰函数,建议直接用高阶函数
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!