rdmcelligott
rdmcelligott

Reputation: 11

JS function showing error without return, but return not necessary

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.

Upvotes: 1

Views: 43

Answers (1)

Alex Wayne
Alex Wayne

Reputation: 187004

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++) {
    //...
  }
}

Upvotes: 4

Related Questions