修饰器(Decorator)是一个函数,用来修改类的行为。这是ES7的一个提案,目前Babel转码器已经支持。本文参考阮一峰老师的文章。
环境安装
目前es7还没出,要让es6支持Decorator就需要安装与配置Babel转码器的插件。
1 .如果项目已经在用npm管理包
//安装
npm i --save-dev babel-plugin-transform-decorators-legacy
2 . 配置项目目录下的.babelrc 文件(babel配置文件),没有就创建一个
//追加大括号内的内容,不懂babel可以搜索相关资料
{
'plugins': ['transform-decorators-legacy']
}
使用
//如果有一个叫,修饰Class
@decoratorA //修饰类
class Person
{
@descratorB //修饰方法
say(message){
}
}
修饰器本质
1.修饰类
//修饰类,以上面的使用为例,实际在编译期间将代码修改成这样
function decoratorA(target){ //Person
//修改target,添加各种方法或者属性等
}
decoratorA(Person);
2.修饰方法
function decoratorB(target, name, descriptor){
// target 修饰的目标对象
// name 方法名
// descriptor对象值如下
// {
// value: specifiedFunction,
// enumerable: false,
// configurable: true,
// writable: true
// };
// 可以通过修改descriptor描述器来修改要
return descriptor;
}
实际应用
- 写一个为类实例添加say方法的修饰器
function sayable(target){
target.prototype.say = function(message){
console.log(message)
}
}
@sayable
class Person{}
var person = new Person();
person.say("good bye"); //"good bye"
2.写一个计算方法执行时间的修饰器
function testable(target, name, descriptor){
let oldValue = descriptor.value;
descriptor.value = function(){
let beginTime = new Date();
let result = oldValue.apply(null, arguments);
let endTime = new Date();
let wasteTime = endTime.getTime() - beginTime.getTime();
console.log(`执行方法'${name}'花了${wasteTime} ms`,arguments, result);
return result;
}
}
class Person{
@testable
countStars(num){
for(var i = 0; i<num;i++){
console.log(`第${i}个星星`);
}
}
}
var haofeng = new Person();
haofeng.countStars(10000);// 数10000个星星试试?
3.如果要计算异步方法的时间呢,我们稍微修改一下
function testable(target, name, descriptor){
let oldValue = descriptor.value;
descriptor.value = function(){
let beginTime = new Date();
let result = oldValue.apply(null, arguments);
let methodArguments = arguments;
if(result instanceof Promise){
result.then(function(data){
let endTime = new Date();
let wasteTime = endTime.getTime() - beginTime.getTime();
console.log(`执行方法'${name}'花了${wasteTime} ms`,methodArguments, data);
});
}else{
let endTime = new Date();
let wasteTime = endTime.getTime() - beginTime.getTime();
console.log(`执行方法'${name}'花了${wasteTime} ms`,arguments, result);
}
return result;
}
}
class Person{
sleep(interval){
return new Promise(function(resolve, reject){
setTimeout(resolve,interval);
});
}
@testable
async countStars(interval){
await sleep(interval);
}
}
var gengzhiBoy = new Person();
gengzhiBoy.countStars(10000);// 数10s星星试试?
总结:
JS修饰器(decorator)其实就那么一回事,只是一个通过@
符号修改类或类属性的一个方法。熟悉使用修饰器将会极大简化代码编写,提高代码可读性。文章新手,纯手打,如有问题,欢迎指正😄