Why is this result [undefined, undefined, undefined] and not [ ]?

const result = [1,2,3].map(n => {
  if(n === 0) {
     return 'hi'
  }
})

console.log(result) // [undefined, undefined, undefined]

When a function exits without using a return, by default, it'll return undefined.

const fn = () => {};
console.log(fn()); // undefined

So, your code is the same as this:

const result = [1,2,3].map(n => {
  if(n === 0) {
     return 'hi'
  } else {
    return undefined
  }
})

console.log(result) // [undefined, undefined, undefined]

And, .map() doesn't give any special treatment to the undefined value - if that gets returned, it'll stick it in the array as normal.

If you're wanting to also filter values out as you map, you'd either use a separate .filter(...) first, or you use .flatMap() like this:

const result = [1,2,3].flatMap(n => {
  if(n === 0) {
     return ['hi']
  } else {
    return []
  }
})

console.log(result) // []

Because the array doesn't contain 0, it only contains 1, 2, and 3.

Array iteration callbacks take the value as the first parameter, and the index as the second.

Wow ... ! Perfect solution!

const objectArray = [{id: 1, title: 'Hello'}, {id: 2, title: 'Hello'}, {id: 3, title: 'Hello'}];

// Before
const result = objectArray.flatMap(n => {
  if (n.id > 3) {
     return n.id
  }
})
console.log(result); // [undefined, undefined, undefined]

// After
const result = objectArray.flatMap(n => {
  if (n.id > 3) {
     return [n.id]
  } else {
     return []
  }
})
console.log(result); // []