Good afternoon, what day have I been struggling with the task of js.I can not understand the logic of the solution of the problem! Someone tell me, please, how she decides on steps.If possible, then also on"syllables"
Actually, here is the task:

//auxiliary function for checking for numbers
function checkNumber(value) {
  return typeof value =='number';
}

//decorator checking types for f
//second argument checks - array with functions to check
function typeCheck(f, checks) {
  return function() {
    for(var i=0;i<arguments.length;i ++) {
      if(! checks[i](arguments[i])) {
        alert("Incorrect type of argument number" + i);
        return;
      }
    }
    return f.apply(this, arguments);
  }
}

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

//wrap the decorator to check
sum=typeCheck(sum,[checkNumber, checkNumber]);//both arguments are numbers

//use the function as usual
alert(sum(1, 2));//3, all is well

//this is how the error will be
sum(true, null);//invalid argument number 0
sum(1,["array","in","sum?!?"]);//invalid argument number 1


In particular, this is exactly what interests you:
if(! Checks[i](arguments[i]))
  • Please, someone explain what this line means:

    if(! checks[i](arguments[i]))
    What does checking here do?
    My opinion is:
    1) checks[i] - are we calling the element with the number"i" or what are we doing?
    2)(arguments[i])) - What are we doing here? call the first argument of the function passed or what? By condition
    The first argument of the function is sum, it turns out that we check checks[i]=0 and sum(0) or what?
    – Annoying5 May 21 '19 at 11:58

2 Answers 2

argumentsis an array of function arguments returned by a typeCheck call to sum.
That is, to call sum(1,2) the array of arguments [1,2].

The string if(! Checks[i](arguments[i])) calls the check function from the checks array at index i, passes in it the argument from arguments at index i and returns the result to condition.
Call:
for(var i=0;i<arguments.length;i ++) {
  if(! checks[i](arguments[i])) {
    alert("Incorrect type of argument number" + i);
    return;
  }
}

in a specific example, sum(1,2) is equivalent to a call:
if(! checkNumber(1)) {
  alert("Incorrect type of argument number 0");
  return;
}
if(! checkNumber(2)) {
  alert("Incorrect type of argument number 1");
  return;
}


In the remaining examples, true and ["array","in","sum?!?"] do not pass the checkNumber check.
  • Thank you so much for a clear explanation! I understood everything, asked a friend on Skype and explained some other points.
    For example, I did not understand where in if() the arguments are taken.This is because the decorator returns another function as a result, and it takes the data for the inner work from the closure! In particular, this moment strained me:
    return function() {
        for(var i=0;i<arguments.length;i ++) {
          if(! checks[i](arguments[i])) {
            alert("Incorrect type of argument number" + i);
            return;
          }
    – Annoying5 May 21 '19 at 15:29
The decorator function wraps another function, adding some functionality to it.For example, in this case, checking the type of the arguments.decorator checking types for f //second argument checks - array with functions to check function typeCheck(f, checks) {   //return a new function, the arguments of which will be collected in an array of args   return function(...args) {     //before executing the function f, check its arguments with the corresponding functions for checking,     //which are in the checks array     for(var i=0;i<args.length;i ++) {       //take the ith function from the array of checking functions and call it with the ith argument from       //array of arguments, the function must return true or false       if(! checks[i](args[i])) {         //if at least one function for checking returned false, output an alert and exit the function.         alert("Incorrect type of argument number" + i);         return;       }     }     //if all checks returned true, call the original function, passing it an array of arguments    //and return the result of the call     return f.apply(this, args);   } }
  • Thank you very much, everything is clear! – Annoying5 May 21 '19 at 15:41