首先我们来看一下装饰器的使用场景及效果
decorator.js
/**
* @description 常用的修饰器
* @author: hruomei
* @update
* @date: 2020-10-19 10:12:17
*/
function isDescriptor(desc) {
if (!desc || !desc.hasOwnProperty) {
return false;
}
const keys = ['value', 'initializer', 'get', 'set'];
for (let i = 0, l = keys.length; i < l; i++) {
if (desc.hasOwnProperty(keys[i])) {
return true;
}
}
return false;
}
function decorate(handleDescriptor, entryArgs) {
if (isDescriptor(entryArgs[entryArgs.length - 1])) {
return handleDescriptor(...entryArgs, []);
} else {
return function () {
return handleDescriptor(...Array.prototype.slice.call(arguments), entryArgs);
};
}
}
function handleReadonly(target, key, descriptor) {
descriptor.writable = false;
return descriptor;
}
function handleLog(target, key, descriptor, [message = '']) {
if (typeof descriptor.value !== 'function') {
throw new SyntaxError('Only functions can be marked as deprecated');
}
return {
...descriptor,
value: function deprecationWrapper() {
this.debug && console.log(`--${key}-- ${message}`, arguments);
return descriptor.value.apply(this, arguments);
}
};
}
function handlePublish(target, key, descriptor, [ event, params ]) {
if (typeof descriptor.value !== 'function') {
throw new SyntaxError('Only functions can be marked as deprecated');
}
return {
...descriptor,
value: function deprecationWrapper() {
descriptor.value.apply(this, arguments);
event && window.EventObserver.emit(event, params);
}
};
}
/**
* @function: readonly
* @description: 禁止修改函数
* @author: hruomei
* @date: 2020-10-26 17:16:36
* @version: V1.0.0
*/
export function readonly(...args) {
return decorate(handleReadonly, args);
}
/**
* @function: log
* @param: {String} message 输出的日志描述信息
* @description: 调用类实例时自动输出日志
* @author: hruomei
* @date: 2020-10-26 17:17:14
* @version: V1.0.0
*/
export function log(...args) {
return decorate(handleLog, args);
}
/**
* @function: publish
* @param: {String} event 事件名
* @description: 调用某个实例方法时发布事件
* @author: hruomei
* @date: 2020-10-26 17:17:54
* @version: V1.0.0
*/
export function publish(...args) {
return decorate(handlePublish, args);
}