0

Reading Eloquent Javascript and one of the examples is

function repeat(n, action) {
  for (let i = 0; i < n; i++) {
    action(i);
  }
}

let labels = [];
repeat(5, x => {
  labels.push(`Unit ${x + 1}`); //what is happening here?
});

console.log(labels);
// → ["Unit 1", "Unit 2", "Unit 3", "Unit 4", "Unit 5"]

Can someone explain how the iteration in the repeat call is working? We are creating a function (x) and passing it in as the action, but how is it aware of what iteration it is on and where does the numeric value that is being pushed to the array come from?

5
  • 2
    action(i) <- i (the current iteration) is passed into the action. Commented Nov 25, 2019 at 21:33
  • it's not aware persay, it just gets x passed in as an argument Commented Nov 25, 2019 at 21:33
  • 1
    Also x is not the function. It's a parameter. It might help writing it as repeat(5, function(x) { ... }) Commented Nov 25, 2019 at 21:34
  • Notice the text Unit ${x + }` is surrounded by a tick rather than a single quote. That is a template literal. ${... } allows you to make a reference to a scoped variable. Commented Nov 25, 2019 at 21:35
  • The function referenced as action is x => { labels.push('Unit ${x + 1}');} (template literal tick marks changed to single quotes for formatting. Those have to be ticks to work) x is the argument passed into this function. Commented Nov 25, 2019 at 21:37

1 Answer 1

1

Lets take a couple of steps back and look at a simpler example.

This is the function you want to call multiple times:

function doSomething(x) {
  labels.push(`Unit ${x + 1}`);
}

It takes an argument which it uses to create a string, and pushes that string to an array.

Of course this is easy to do with a loop:

for (let i = 0; i < 5; i++) {
  doSomething(i);
}

It should be obvious here that we pass the loop variable (i) to our function, which is assigned to parameter x. It's the same as doing:

doSomething(0);
doSomething(1);
...

This code is not reusable though. Say we want to call the function a different number of times, not just (and always) five times.
We can put the loop in a function itself, taking the number of times as a parameter:

function repeat(n) {
  for (let i = 0; i < n; i++) {
    doSomething(i);
  }
}

Now we can call the function as repeat(5) or repeat(10) and it will call doSomething that many times.

However, now we want to call another function multiple times. We could create a second repeat function (with a different name of course), but that is not ideal.
Instead of referring to doSomething directly in repeat, we can change repeat to accept a second parameter whose value should be a function value. This is possible because functions are values like any other in JavaScript:

function repeat(n, action) {
  for (let i = 0; i < n; i++) {
    action(i);
  }
}

Now we can reuse repeat to call any function we want:

repeat(5, doSomething)
repeat(10, doSomethingElse)

And that's what the code above is doing.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.