Javascript decorator

Один из любимейших приемов. В двух словах: декоратор возвращает функцию, которая выполняет декорируемую исходную функцию и вместе с ней выполняет еще одну (или две). Практическая польза декорирования ощущается при отладке и логировании на высшем уровне, когда исследуется поведение всей системы, а не деталей реализации методов. Второй, немного грязный случай — использование декоратора для шлифования уже существующих методов налету. Третий — переписывание стандартных методов для исследование кода внешних источников (например рекламных блоков).

Основные проблемы:
  • нечитаемость функции после декорирования (toString выводит код декоратора);
  • эффект неожиданности, когда функция выполняет не только то, что было описано при ее объявлении;
  • некорректная работа в случае, когда декорируемая функция используется как объект для хранения свойств и методов, которые сама же и использует
function decorate (initial, decorate_before, decorate_after) {
	return function () {
		var initial_call_result;

		if (typeof decorate_before === 'function') {
			decorate_before.apply(this, arguments);
		}
		initial_call_result = initial.apply(this, arguments);
		if (typeof decorate_after === 'function') {
			decorate_after.apply(this, arguments);
		}
		return initial_call_result;
	}
}

gist

Реализации могут варьироваться. В конкретном случае исходную функцию можно декорировать как «до» так и «после». Например логирование использования document.write
document.write = decorate(document.write, null, function (str) {
	console.log( 'Document write call with "' + str + '" argument' );
});
Share
Send
1 comment
Поллеский
Чудеса декорации
Popular