装饰器
装饰器(Decorator)是一种与类(class)相关的语法,用来注释或修改类和类方法。
装饰器是一种函数,写成@ + 函数名。它可以放在类和类方法的定义前面。
(引用自《ECMAScript 6 入门》)
用于装饰类
function demo(target) {
console.log('name:', target.name);
target.isDemo = true;
}
@demo
class Example {
sayHi() {
console.log('Hi')
}
}
console.log('Example', Example.isDemo);
用于装饰属性和方法
- 设置类成员为只读
function readOnly(target, name, descriptor) {
console.log('target', target);
console.log('name', name);
console.log('descriptor', descriptor);
descriptor.writable = false;
}
class Example {
@readOnly
isTest = true;
@readOnly
sayHi() {
console.log('Hi')
}
}
let ex = new Example();
ex.sayHi();
try {
ex.isTest = false;
} catch(err) {
console.log('报错:' + err.message);// 报错:Cannot assign to read only property 'isTest' of object '#<Example>'
}
- 输出日志
function log(target, name, descriptor) {// 调用方法前输出日志
var oldValue = descriptor.value;
descriptor.value = function() {
console.log(`Calling function ${name} with ${Object.values(arguments)}, result: `, oldValue.apply(this, arguments));
return oldValue.apply(this, arguments);
};
return descriptor;
}
class Example {
@log
add(a, b) {
return a + b;
}
}
let ex = new Example();
ex.add(2, 3);
同时使用多个装饰器
function demo(id) {
console.log('demo', id);
return (target, name, desc) => {
console.log('target', target);
console.log('name', name);
console.log('desc', desc);
};
}
class Example {
@demo(1)
@demo(2)
method() {
console.log('method');
}
}
let ex = new Example();
ex.method();
// 先输出demo 1,后输出demo 2