Why does reassigning work rather than just returning in concat?

Just trying to figure out why reassigning works as opposed to just returning. I know there are probably better ways of doing this but I just want to understand.

Given: const anArray = [1, 'foo', 2, 'bar']

 const getConcatenatedStr = (arr) => {
      let result = ''
      if (arr && arr.length > 1) {
         arr.forEach(() => {
            return result.concat('๐Ÿ˜Ž', ' ')
         })
       } else {
         result = '๐Ÿ˜Ž'
      }
      return result.trim()
   }

console.log('result one:', getConcatenatedStr(anArray)) returns ‘result one: ‘

 const getConcatenatedStrReassign = (arr) => {
      let result = ''
      if (arr && arr.length > 1) {
         arr.forEach(() => {
            result = result.concat('๐Ÿ˜Ž', ' ')
            return result
         })
       } else {
         result = '๐Ÿ˜Ž'
      }
      return result.trim()
   }

console.log('result two: ', getConcatenatedStrReassign(anArray)) returns result two: ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž ๐Ÿ˜Ž

Of course, this works as well, equal to getConcatenatedStrReassign:

    // ...
      if (arr && arr.length > 1) {
            return result = result.concat('๐Ÿ˜Ž', ' ')
         })
    // ...

Answer

forEach takes a callback as an argument and performs that callback on each index of an array and returns undefined. So when your callback in the first example returns result.concat() you’re really just returning undefined and not ever concatenating. That’s why the second example works, you’re actually reassigning result. The return in the second example is still superfluous because all it does is return undefined. Check out the docs for Array.forEach for a little more of an explanation here.