Decorator
- 修饰器的意思
- 修饰器是一个函数,用来修改类的行为(即扩展类的功能)
- 修饰器是一个函数
- 修改行为
- 修改类的行为
- 通过修饰器可以修改类的行为
基本概念
- 修饰器是个函数
- 修改行为(扩展类的功能)
- 只在类中有用
基本用法
babel-polyfill不能处理Decorator,需要一个插件
babel-plugin-transform-decortators-legacy
{
//使用修饰器提供一个功能:限定某个属性是只读的
let readonly=function(target,name,descriptor){
//target:修改的类本身
//name:修改什么属性名称
//descriptor:该属性的描述对象
descriptor.writable=false;//将属性的描述对象“写”设置为false
return descriptor//返回属性描述对象
};
class Test{
@readonly//readonly就是修饰器的名称
time(){
return '2019-08-11'
}
}
let test=new Test();//生成一个实例
test.time = function(){
console.log('reset time')
}
console.log(test.time());//报错
//readonly修饰器不会允许你对只读属性的方法赋值,不加修饰器是可以赋值的
//加了修饰器,就是对类本身的方法进行了修改
}
//在类的外面加修饰器(一定要在class前面,其他地方不行)
{
let typename=function(target,name,descriptor){
target.myname='hello';//在目标类上增加一个静态属性myname='hello'
}
@typename//在class前面加上typename修饰器
class Test{
}
console.log('类修饰符',Test.myname);//hello
}
第三方库修饰器的js库:core-decorators;npm i core-decorators
Decorator修饰器的应用
- 日志系统,前端需要做埋点,做埋点就需要有日志
- 传统做法:把埋点写在业务逻辑中,比如说页面中的广告,为这个广告做哪些统计呢?一个是点击一个是展示,之前的做法是展示的时候,我们判断下展示,然后在展示函数中发一个埋点的函数执行一下,然后在点击的呢,在点击的函数里执行一下
- 使用修饰器,做不一样的写法
{
let log=(type)=>{//type表示click还是show
return function(target,name,descriptor){
let src_method=descriptor.value;//保存原始函数体
descriptor.value=(...arg)=>{//descriptor.value方法重新赋值
src_method.apply(target,arg);//原来的方法先执行,埋点后执行
console.info(`log ${type}`);//模拟埋点//这段话,在实际开发中换成埋点语句就可以,//new img.src='接口'
}
}
}
class AD{//广告的类
@log('show')
show(){
console.info('ad is show')
}
@log('click')
click(){
console.info('ad is click')
}
}
let ad=new AD();//实例化
ad.show();
ad.click();
//ad is show
//log show
//ad is click
//log click
}
这样写埋点的好处
- 把埋点系统抽离出来,成为一个可复用的模块
- 如果将来埋点系统变了,发送通信方式变了,只需要改console.info(
log ${type}
);就可以了,class AD 几乎可以不用动,这样就保证了代码的可复用性 - 埋点系统拆离出去后,业务代码(class AD)简洁度提升,可维护性提升