2

I got a strange experience today while playing with js.

-> 'N'+ +'78' this is equal to "N78"

-> '78' + + 'g' this is equal to "78NaN"

-> '1' + + '5' this is equal to '15' but

-> 1 + + '5' is equal to 6 and

-> 1 + '5' is again equal to '15'.

I understand the last point but not sure how JavaScript treats + + operators in the string.

Pooja Kushwah
  • 189
  • 2
  • 2
  • 13
  • Very interesting. – cape_bsas Dec 17 '20 at 18:49
  • 1
    Coercion is a funky thing. See [this article](https://www.freecodecamp.org/news/js-type-coercion-explained-27ba3d9a2839/) for more info. – Phix Dec 17 '20 at 18:52
  • The `+` operator is working in three different ways here: Concatenation, addition, and negation (though because it's `+` and not `-`, you don't get a sign change). The rest is from type coercion since the things the operator works on need to be of the same type and javascript is helpful like that. – Ouroborus Dec 17 '20 at 18:56
  • 1
    Hot take, I suppose: When I was in college, I believed that understanding these detailed rules of how a language is parsed represented knoweldge. Then in the working world I found out that I have to use multiple languages that probably don't agree on these things - often several on the same project (especially where js is involved) - and this is just one of the reasons I came to relalize that unless you're writing a js parser, the only practical answer is "don't write code like that". – Mark Adelsberger Dec 17 '20 at 19:57
  • [Duplicate](https://stackoverflow.com/search?q=code%3A%22%2B+%2B%22+%5Bjs%5D) of [what it will print console.log(1+ + "2")](https://stackoverflow.com/q/28493464/4642212). – Sebastian Simon Dec 17 '20 at 21:05

1 Answers1

3

Here's some important rules:

  1. The unary + operator coerces a value to a number.
  2. a + + b is interpreted as a + (+b).
  3. a + b will either add numbers or concatenate strings.
    • if a and b are numbers, it will add them.
    • If either/both of a or b is not a number, it will coerce either/both to a string and then concatenate them.

Due to these rules, it's usually preferred to use template literals for string concatenation. And for math use parseInt or parseFloat to convert strings with numbers to actual numbers before using them with math operators. This will help keep you sane, because (as you've noticed) it gets a little weird when you write code like that.


So knowing the above rules, we can work through your examples:

 'N'+ +'78'
 'N' + (+'78') // how interpreter sees it
 'N' + 78      // unary + changes string '78' to number 78
 'N78'         // string + number coerces the number to a string.

'78' + + 'g'
'78' + (+'g') // how interpreter sees it
'78' + NaN    // unary + cannot convert 'g' to number, so NaN is returned instead.
'78NaN'       // NaN is coerced to a string and concatenated with the string '78'

'1' + + '5'
'1' + (+'5') // how interpreter sees it
'1' + 5      // unary + converts string '5' to number 5
'15'         // string + number coerces the number to a string and concatenates.

1 + + '5'
1 + (+'5') // how interpreter sees it
1 + 5      // unary + converts string '5' to number 5
6          // both operands are numbers, addition is performed.

1 + '5'
'15'       // number + string coerces the number to a string and concatenates.

You can even control this coercion by implementing a toString method on your own objects.

const myObjA = {
  toString: () => 'A'
}

const myObjB = {
  toString: () => 'B'
}

console.log(123 + myObjA + myObjB) // '123AB'
Alex Wayne
  • 178,991
  • 47
  • 309
  • 337