1

I was trying to write a simple function that prints a multiplication table and came up with the solution below:

const oneToTwelveMultiplicationTable = () => {
  [...Array(12).keys()].forEach((num1, i) => {
    [...Array(12).keys()].forEach((num2, j) => {
      console.log((num1 + 1) * (num2 + 1))
    })
  })
}

oneToTwelveMultiplicationTable()

It works fine and that's not the issue, the issue is, as I was trying to clean up the formatting of the response (I wanted a more table-like format), I made this edit:

const oneToTwelveMultiplicationTable = () => {
  let result = []

  [...Array(12).keys()].forEach((num1, i) => {
    [...Array(12).keys()].forEach((num2, j) => {
      console.log((num1 + 1) * (num2 + 1))
    })
  })
}

oneToTwelveMultiplicationTable()

That gives an error on the 4th line, which I was able to fix by adding a return in front of it:

const oneToTwelveMultiplicationTable = () => {
  let result = []

  return [...Array(12).keys()].forEach((num1, i) => {
    [...Array(12).keys()].forEach((num2, j) => {
      console.log((num1 + 1) * (num2 + 1))
    })
  })
}

oneToTwelveMultiplicationTable()

My question is why do I need that return? I am not trying to get the function to return a value, why does adding a return in front of the forEach fix the error, and why does adding a variable declaration cause an error in the first place? This should be uncomplicated but I'm not clear as to why this is happening.

3
  • is there an actuall reason for the result array? Commented Oct 17, 2018 at 18:34
  • @goldie If I take out the return the function errors. Commented Oct 17, 2018 at 18:40
  • @Talg123 I added it because I wanted to change the format of the way it printed to the console. I'm able to get the function to work, but this is more about me trying to understand why the return corrects the error and what the error actually is. Commented Oct 17, 2018 at 18:41

1 Answer 1

4

The problem is automatic semicolon insertion or ASI. This is a "feature" of javascript that sort of allows semicolons to be optional, but it really just inserts them for you, sometimes. This usually works fine, but when a line begins with [ or (, a semicolon is not inserted at the end of the previous line.

So these two expressions:

let result = []
[...Array(12).keys()]

Are interpreted as one expression:

let result = [][...Array(12).keys()]

Which doesn't really work at all.

The reason that the return works is that it prevents the line from starting with a [ and so the interpreter puts a semicolon at the end of the previous line for you.

To fix it you could use semicolons:

let result = [];
[...Array(12).keys()]

Or, use simple for loops that would dodge the issue

for (num1 = 0; num1 < 12; num1++) {
  for (num2 = 0; num2 < 12; num2++) {
    //...
  }
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! That makes a ton of sense, I really appreciate your time.
One more reason to always put in the semi-colons and just stop making the parser do that for you! I was going to post that same thing...no need to dodge about then :)

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.