JavaScript: TypeError: work.calls не повторяется в декораторе функций (вопрос для начинающих) - PullRequest
0 голосов
/ 27 сентября 2018

Я пытался передать функцию work в декоратор, где она будет сохранять вызовы функций в массиве work.calls.

Функция:

work(a, b) {
  console.log(a + b);
}

Декоратор:

function decorator(func) {
  func.calls = [];
  return function(...args) {
    func.calls.push(args);
    return func.call(this, ...args);
  }
}

Декорирование функции work:

work = decorator(work);

Вызов новой функции:

work(1, 2); // 3
work(4, 5); // 9

for (let args of work.calls) {
  console.log( 'call:' + args.join() ); // TypeError: work.calls is not iterable
}

work.calls - это массив, так почему он не повторяется?

Для справки, есть еще одна версия декоратора, написанная кем-то другим, которая на самом деле работает:

function decorator(func) {

  function wrapper(...args) {
    wrapper.calls.push(args);
    return func.apply(this, arguments);
  }

  wrapper.calls = [];

  return wrapper;
}

work(1, 2); // 3
work(4, 5); // 9

for (let args of work.calls) {
  alert( 'call:' + args.join() ); // "call:1,2", "call:4,5"
}

Что здесь делает wrapper и почему этот способ работает?

1 Ответ

0 голосов
/ 27 сентября 2018

2 функции не работают одинаково.Ваш декоратор определяет свойство calls переданной функции.Другая функция декоратора устанавливает свойство для вложенной и возвращаемой (wrapper) функции.Вы получаете эту ошибку, поскольку work.calls равно undefined.Декорированный work относится к анонимной функции: return function(...args), которая не имеет свойства calls.

Если вы измените work = decorator(work); на let work2 = decorator(work);, вы увидите, что calls установлено на исходную функцию work, а не на work2.

Ваш код работаетТо же самое, если вы определяете свойство calls в возвращаемой функции замыкания.

function decorator(func) {
  function __(a, b) {
    __.calls.push([a, b])
    return func(a, b)
  }
  __.calls = []
  return __;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...