Here's some important rules:
- The unary
+
operator coerces a value to a number.
a + + b
is interpreted as a + (+b)
.
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'