ES7中提供了一个装饰器注解Descriptor:
安装
npm i babel-plugin-transform-decorators-legacy babel-register --save-dev
在.babelrc文件中添加插件信息
"plugins": ["transform-decorators-legacy"],
修饰类
给修饰的类添加上blood属性和set/get方法,装饰一个类时只有一个参数target
, 指向该类(构造器),可以使用target.prototype
获取类原型。
export function superHero(target){
Object.defineProperties(target.prototype,{
'blood':{
value:'1',
writable:true
},
'setBlood':{
value:function(val){
this.blood = val;
}
},
'getBlood':{
value:function(){
return this.blood
}
}
})
}
@superHero
class Person {
constructor(name) {
this.name = name;
}
setName(value){
this.name = value
}
getName() {
return this.name;
}
}
let p = new Person('ljp');
p.setBlood(100);
console.log(p) //Person {name: "ljp", blood: 100}
如果需要使用注解传递参数,需要在装饰类外部再嵌套一层函数。
export function China(val){
return function(target){
target.prototype.contury = val
}
}
@China('China')
class Person{
//.......
}
修饰方法
descriptor.value
是修饰方法时特有的属性,值为修饰的方法。
function nameLog(target,key,descriptor){
let fn = descriptor.value; //保存原有函数
descriptor.value = function(...args) {
// 拓展执行一些日记操作 args是外部调用setName传入的参数,这里相当于重写函数体
// .....
// 执行原有setName方法, 装饰器中this为undefined,因此方法中的this不受此影响
return fn.apply(this, args);
};
return descriptor;
}
class Person {
constructor(name) {
this.name = name;
}
@nameLog
setName(value){
this.name = value
}
getName() {
return this.name;
}
}
修饰变量
修饰变量时参数和修饰方法一样,但也有一个特有属性descriptor.initializer
,返回的是属性值
ƒ initializer() {
return 19;
}
可以使用 descriptor.initializer()来获取修饰的变量值
function readOnly(target,key,descriptor){
let v = descriptor.initializer();
descriptor.writable = false;
return descriptor
}
class Person {
@readOnly
age = 19;
}