What is higher order function ?
Functions that operate on other functions, either by taking them as
arguments or by returning them, are called higher-order functions.
Let me start with a small example and then we get back to the problem in the question.
function evenNumberFilter(number) {
  return number%2==0
}
function oddNumberFilter(number) {
  return !evenNumberFilter(number)
}
evenNumberFilter(2) // true
oddNumberFilter(3)  // true
 
 
Now we know if we call function
- evenNumberFilterwith- parameter Xit will return- trueif it is even number
- oddNumberFilterwith- parameter Xit will return- trueif it is odd number
Let's extend the problem and say
- "I would like to have all even numbers till number 10"
- "I would like to have all odd numbers till number 10"
function evenNumberFilter(number) {
  return number %2 == 0
}
function oddNumberFilter(number) {
  return !evenNumberFilter(number)
}
function evenNumberBeforeTen() {
  const result = []
  for(number=0; number<10; number++) {
    if (evenNumberFilter(number)) {
      result.push(number)
    }
  }
  return result
}
function oddNumberBeforeTen() {
  const result = []
  for(number=0; number<10; number++) {
    if (oddNumberFilter(number)) {
      result.push(number)
    }
  }
  return result
}
evenNumberBeforeTen();  //[0,2,4,6,8]
oddNumberBeforeTen();   //[1,3,5,7,9]
 
 
If we look at the code both evenNumberBeforeTen and oddNumberBeforeTen share good amount of common code
- The way for loop is itereated
- The way result is appended to an array
- The result that is returned at the end of the function.
Only difference between these two functions is, what filter it operates on either evenNumberFilter or oddNumberFilter.
So can we refactor the code and write one generic filter function which can take the predicate as a parameter ?
Predicate: a boolean-valued function P: X? {true, false}.
In our case both evenNumberFilter and oddNumberFilter are
predicates
function evenNumberFilter(number) {
  return number %2 == 0
}
function oddNumberFilter(number) {
  return !evenNumberFilter(number)
}
function filter(predicate) {
  const result = []
  for(number=0; number<10; number++) {
    if (predicate(number)) {
      result.push(number)
    }
  }
  return result
}
filter(evenNumberFilter);  //[0,2,4,6,8]
filter(oddNumberFilter);   //[1,3,5,7,9]
 
 
Now, in the above example function filter is higher order function because it takes function predicate as parameter.
Let's get into the problem you mentioned in the question.
repeat is a higher order function which takes number and function action as a parameter.
unless is a higher order function which takes boolean and function then as a parameter
When you execute
repeat(3, n => {
  unless(n%2 == 1, () => {
    console.log(`${n} is even`);
  });
});
- repeatis called first and then it will execute function below 3 times.
function (n) => {
  unless(n%2 == 1, () => {
    console.log(`${n} is even`);
});
 
 
- When above function is called with parameters 0,1,2. It calls unlessfunction with boolean ofn%2==1which will be eithertrueorfalseand function below as parameter.
function() => {
  console.log(`${n} is even`);
});
 
 
When unless is called with true and then it will not execute the then function so no log is printed
When unless is called with false and then it will  execute the then function which prints the log