Как объяснить задачу по Функции-обёртки, декораторы?

Уже какой день бьюсь над задачей по js. Я не могу понять логику решения задачи! Кто-нибудь обхясните мне, пожалуйста, как она решает по шагам. Если можно, то еще и по "слогам"
Собственно, вот задача:

// вспомогательная функция для проверки на число
function checkNumber(value) {
  return typeof value == 'number';
}

// декоратор, проверяющий типы для f
// второй аргумент checks - массив с функциями для проверки
function typeCheck(f, checks) {
  return function() {
    for (var i = 0; i < arguments.length; i++) {
      if (!checks[i](arguments[i])) {
        alert( "Некорректный тип аргумента номер " + i );
        return;
      }
    }
    return f.apply(this, arguments);
  }
}

function sum(a, b) {
  return a + b;
}

// обернём декоратор для проверки
sum = typeCheck(sum, [checkNumber, checkNumber]); // оба аргумента - числа

// пользуемся функцией как обычно
alert( sum(1, 2) ); // 3, все хорошо

// а вот так - будет ошибка
sum(true, null); // некорректный аргумент номер 0
sum(1, ["array", "in", "sum?!?"]); // некорректный аргумент номер 1


В частности интересует именно вот эта строка:
if (!checks[i](arguments[i]))
  • Вопрос задан
  • 114 просмотров
Решения вопроса 1
rockon404
@rockon404
Frontend Developer
arguments - массив аргументов функции возвращаемой вызовом typeCheck в sum.
То-есть для вызова sum(1,2) массив аргументов [1,2].

Строка if (!checks[i](arguments[i])) вызывает функцию проверки из массива checks по индексу i, передает в нее аргумент из arguments по индексу i и возвращает результат в условие.
Вызов:
for (var i = 0; i < arguments.length; i++) {
  if (!checks[i](arguments[i])) {
    alert("Некорректный тип аргумента номер " + i);
    return;
  }
}

в конкретном примере sum(1,2), эквивалентен вызову:
if (!checkNumber(1)) {
  alert("Некорректный тип аргумента номер 0");
  return;
}
if (!checkNumber(2)) {
  alert("Некорректный тип аргумента номер 1");
  return;
}


В остальных примерах true и ["array", "in", "sum?!?"] не проходят проверку checkNumber.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@kova1ev
Функция-декоратор оборачивает другую функцию, добавляя ей некоторую функциональность. Например, в данном случае - проверка типа аргументов. Может быть, чуть более понятно будет если переписать декоратор так:
// декоратор, проверяющий типы для f
// второй аргумент checks - массив с функциями для проверки
function typeCheck(f, checks) {
  //возвращаем новую функцию, аргументы которой будут собираться в массив args
  return function(...args) { 
    //перед выполнением функции f проверим её аргументы соответствующими функциями для проверки,
    //которые находятся в массиве checks              
    for (var i = 0; i < args.length; i++) {
      //берем из массива проверочных функций i-тую функцию и вызываем ее с i-тым аргументом из
      //массива аргументов, функция должна возвращать true или false
      if (!checks[i](args[i])) {
        //если хоть одна функция для проверки вернула false, выводим алерт и выходим из функции.
        alert( "Некорректный тип аргумента номер " + i );
        return;
      }
    }
    //если все проверки вернули true, вызываем исходную функцию, передавая ей массив аргументов
   //и возвращаем результат вызова
    return f.apply(this, args);
  }
}
Ответ написан
Ваш ответ на вопрос

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

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