Задавая этот вопрос, я полностью упустил из виду один неловко тривиальный аспект. Сама функция декоратора вызывается только один раз для каждого объявления метода. Если декоратор вычисляется во время инициализации для функции no-op, накладные расходы будут возникать только во время инициализации, и они будут довольно минимальными, как показано в коде ниже.
Инстанцирование класса и вызовы функций во время выполнения функций, отмеченных с помощью декоратора @log
, будут свободны от любых издержек.
const DEBUG = false;
const logDebug = function(_target: any, key: string, descriptor: PropertyDescriptor): any {
console.log("log(): called");
const originalMethod = descriptor.value;
descriptor.value = function(...args: any[]) {
const functionName = key;
console.log(functionName + "(" + args.join(", ") + ")");
const result = originalMethod.apply(this, args);
console.log("=> " + result);
return result;
};
return descriptor;
};
const logNoop = function() {};
const log = DEBUG ? logDebug : logNoop;
class Test {
@log
test(a: number, b: number) {
console.log("test(): called", a, b);
}
}
new Test().test(1, 2);
new Test().test(3, 5);
Фрагмент скомпилированного JS, чтобы показать, что издержки действительно минимальны:
var Test = /** @class */ (function () {
function Test() {
}
Test.prototype.test = function (a, b) {
console.log("test(): called", a, b);
};
__decorate([
log
], Test.prototype, "test", null);
return Test;
}());