вернуться к уроку

Логирующий декоратор (1 аргумент)

важность: 5

Создайте декоратор makeLogging(f, log), который берет функцию f и массив log.

Он должен возвращать обёртку вокруг f, которая при каждом вызове записывает («логирует») аргументы в log, а затем передаёт вызов в f.

В этой задаче можно считать, что у функции f ровно один аргумент.

Работать должно так:

function work(a) {
  /* ... */ // work - произвольная функция, один аргумент
}

function makeLogging(f, log) { /* ваш код */ }

var log = [];
work = makeLogging(work, log);

work(1); // 1, добавлено в log
work(5); // 5, добавлено в log

for (var i = 0; i < log.length; i++) {
  alert( 'Лог:' + log[i] ); // "Лог:1", затем "Лог:5"
}

Открыть песочницу с тестами для задачи.

Возвратим декоратор wrapper который будет записывать аргумент в log и передавать вызов в f:

function work(a) {
  /*...*/ // work - произвольная функция, один аргумент
}

function makeLogging(f, log) {

  function wrapper(a) {
      log.push(a);
      return f.call(this, a);
    }

  return wrapper;
}

var log = [];
work = makeLogging(work, log);

work(1); // 1
work(5); // 5

for (var i = 0; i < log.length; i++) {
  alert( 'Лог:' + log[i] ); // "Лог:1", затем "Лог:5"
}

Обратите внимание, вызов функции осуществляется как f.call(this, a), а не просто f(a).

Передача контекста необходима, чтобы декоратор корректно работал с методами объекта. Например:

user.method = makeLogging(user.method, log);

Теперь при вызове user.method(...) в декоратор будет передаваться контекст this, который надо передать исходной функции через call/apply.

function makeLogging(f, log) {

  function wrapper(a) {
    log.push(a);
    return f.call(this, a);
  }

  return wrapper;
}

Открыть решение с тестами в песочнице.