Why in this case order of conditions matter?

Hi everyone

First of all sorry for the dumb question.

I’m a newbie and can’t really figure out by myself why in this case (in this particular order)

const recordCollection = {
  2548: {
    albumTitle: 'Slippery When Wet',
    artist: 'Bon Jovi',
    tracks: ['Let It Rock', 'You Give Love a Bad Name']
  },
  2468: {
    albumTitle: '1999',
    artist: 'Prince',
    tracks: ['1999', 'Little Red Corvette']
  },
  1245: {
    artist: 'Robert Palmer',
    tracks: []
  },
  5439: {
    albumTitle: 'ABBA Gold'
  }
};

function updateRecords(records, id, prop, value) {
  if(prop !== 'tracks' && value) {
    records[id][prop] = value
  } else if (prop === 'tracks' && !records[id].hasOwnProperty(prop)) {
    records[id][prop] = [value]
  } else if (prop === 'tracks' && records[id].hasOwnProperty(prop)) {
    records[id][prop].push(value)
  } else if (!value) {
    delete records[id][prop]
  }

  return records
}
console.log(updateRecords(recordCollection, 2548, "tracks", ""))

condition

else if (!value) {
  delete records[id][prop]
}

will not work as expected (is not deleting ‘tracks’ property) until being swapped with

else if (prop === 'tracks' && records[id].hasOwnProperty(prop)) {
  records[id][prop].push(value)
}

>Solution :

That’s because when prop is 'tracks' one of the following two conditions
will always be true

} else if (prop === 'tracks' && !records[id].hasOwnProperty(prop)) {
  records[id][prop] = [value]
} else if (prop === 'tracks' && records[id].hasOwnProperty(prop)) {
  records[id][prop].push(value)
}

Because !records[id].hasOwnProperty(prop) is a negation of records[id].hasOwnProperty(prop), which means when prop === 'tracks' is true, one of the above else ifs will also be true, thus always skipping all else if checks (and blocks) that follow them (and the else block, but here it is not present).

Additionally, it is important to keep in mind that boolean expressions and thus also checks in if/else if statements short-circuit in many programming languages, which means that the checks are done in order and as soon as one condition is true its block is executed and all remaining checks are skipped (they are not even attempted). Only in the case when all conditions would return false, only then all conditions would have been fully evaluated.

Leave a Reply