Такого рода модификации прототипа класса никогда не выполняются внутри конструктора - главным образом потому, что конструктор класса отвечает за управление текущим экземпляром класса, а не всеми экземплярами класса. Предполагается, что конструктор объявляет новые методы ('log', 'info' и т. Д.) В экземпляре класса this
, это менее эффективно, чем объявление методов в классе prototype
, и может быть желательным или нет для дальнейшего наследования класса.
Это то, для чего предназначены декораторы. Они предоставляют удобный синтаксис для конструктора и прототипа класса расширения или модификации.
Декоратор может изменить существующий класс prototype
:
function withLogger(Class) {
['log','info','error','warn','group','groupEnd'].forEach(func => {
Class.prototype[func] = function() {
return this.callConsoleMethod(func, ...arguments);
};
});
return Class;
}
Или возвращать новый класс, который расширяет существующий класс неразрушающим способом, это позволяет ссылаться на оригинальные члены с super
при дублировании их в классе-обертке.
Декораторы имеют аккуратный синтаксис в ECMAScript Next / TypeScript:
@withLogger
class YaLog {
...
}
Поскольку декоратор в основном является вспомогательной функцией, его можно применить непосредственно в ES6 чуть менее выразительным образом:
const YaLog = withLogger(class YaLog {
...
});