javascriptoperator-precedenceassignment-operatoraugmented-assignment

Why is `foo += a || b` not equivalent to `foo = foo + a || b`?


as far as I understand, the additional assignment operator simply shortens the way we increment a value, e.g, instead of writing x = x + 1 for instance, we use x += 1, Now, here is an example of a case that this approach didn't work for me as intended. I want to loop through a given string, add the current character to a predeclared empty object, if the character already exists in the object, i will increment its value by 1, if it does not, then I will add it with the value of 1. in other words I am building a character map of a given string.

let charMap = {}

for (let char of 'doooppy') {
  charMap[char] = charMap[char] + 1 || 1;
}

this works like a charm. now check the following

let charMap = {} 

for (let char of 'doooppy') {
  charMap[char] += 1 || 1;
}

this now returns a NaN, which is pretty weird to me as its the same idea of using the assignment operator. can somebody explain why is that ?! thanks.


Solution

  • 1 || 1 is being evaluated before charMap[char] += 1 || 1; is evaluated. That's the way operator precedence in JavaScript works. The part with || is evaluated before the part with +=. The first time that line of code is run, charMap[char] is undefined. Using += on undefined returns NaN, and then in subsequent executions using += on NaN also returns NaN.

    Correct solution with += would be:

    let charMap = {} 
    
    for (let char of 'doooppy') {
      if (!charMap[char]) {
        charMap[char] = 1;
      } else {
        charMap[char] += 1;
      }
    }