Как он узнает, что (3, 5) — это arguments?

Код:

let worker = {
  slow(min, max) {
    alert(`Called with ${min},${max}`);
    return min + max;
  }
};

function cachingDecorator(func, hash) {
  let cache = new Map();
  return function() {
    let key = hash(arguments); // (*)
    if (cache.has(key)) {
      return cache.get(key);
    }

    let result = func.call(this, ...arguments); // (**)

    cache.set(key, result);
    return result;
  };
}

function hash(args) {
  return args[0] + ',' + args[1];
}

worker.slow = cachingDecorator(worker.slow, hash);

alert( worker.slow(3, 5) ); // работает
alert( "Again " + worker.slow(3, 5) );

Вопросы:

1) Как он узнает, что в let key = hash(arguments); на месте argumentsдолжны быть 3, 5 ?
2) Почему изменив одновременно(или в одном из мест) здесь let key = hash(arguments); и здесь let result = func.call(this, ...arguments); название arguments, например, на argument- код перестает работать и выдает ошибку?
  • Вопрос задан
  • 169 просмотров
Решения вопроса 1
delphinpro
@delphinpro Куратор тега JavaScript
frontend developer
arguments - это массив массиво-подобный объект аргументов, всегда присутствующий в функции (кроме стрелочных).
Тут используется декоратор – функция-обёртка над другой функцией.
Изначальная функция worker.slow()оборачивается в новую функцию-декоратор. Декоратор выполняет некую работу, вызывает оригинальную функцию, с ее результатом может выполнить еще какую-то работу, и возвращает итоговый результат.

После выполнения этой строчки
worker.slow = cachingDecorator(worker.slow, hash);
в worker.slow у вас уже не оригинал, а декоратор. Т.е. эта функция
function() {
    let key = hash(arguments); // (*)
    if (cache.has(key)) {
      return cache.get(key);
    }

    let result = func.call(this, ...arguments); // (**)

    cache.set(key, result);
    return result;
  };


Именно она выполняется в последней строчке. Сюда передаются аргументы 3 и 5, которые и попадают в зарезервированный массив arguments.

Можно переписать так, чтобы лучше понять, что происходит:

function cachingDecorator(func, hash) {
  let cache = new Map();
  return function(arg1, arg2) { // явно указать аргументы
    let key = hash(arg1, arg2); // (*)
    if (cache.has(key)) {
      return cache.get(key);
    }

    let result = func.call(this, arg1, arg2); // (**)

    cache.set(key, result);
    return result;
  };
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы