Why does JavaScript handle the plus and minus operators between strings and numbers differently?

JavascriptStringNumbersOperators

Javascript Problem Overview


I don't understand why JavaScript works this way.

console.log("1" + 1);
console.log("1" - 1);

The first line prints 11, and the second prints 0. Why does JavaScript handle the first as a String and the second as a number?

Javascript Solutions


Solution 1 - Javascript

String concatenation is done with + so Javascript will convert the first numeric 1 to a string and concatenate "1" and "1" making "11".

You cannot perform subtraction on strings, so Javascript converts the second "1" to a number and subtracts 1 from 1, resulting in zero.

Solution 2 - Javascript

+ is ambiguous. It can mean "concatenate" or "add". Since one side is a string, it is taken to mean "concatenate", hence the result is 11 (which, by the way, was one of my favourite jokes as a young child. That and "1 + 1 = window", as shown visually: │┼│ ニ ⊞)

- however has only one meaning: subtract. So it subtracts.

This kind of problem is not present in other languages such as PHP, where "concatenate" is . instead of +, making no ambiguity. Still other languages like MySQL don't even have a concatenation operator, instead using CONCAT(a,b,c...).

Solution 3 - Javascript

Because the spec explicitly tells to do so. Page 75. Note the difference between 11.6.1 steps 5-8 and 11.6.2 steps 5-7.

> 11.6.1 - describes how addition operator works

1-4. ...

5. Let lprim be ToPrimitive(lval).

6. Let rprim be ToPrimitive(rval).

7. If Type(lprim) is String or Type(rprim) is String, then

7a. Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)

8. Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim)

> 11.6.2 - describes how subtraction operator works

1-4. ...

5. Let lnum be ToNumber(lval).

6. Let rnum be ToNumber(rval).

7. Return the result of applying the subtraction operation to lnum and rnum

Summary In case of addition if any of the operands when converted to primitive value without any hints suddenly becomes a string the second one is converted to a string too. In case of subtraction both operands are converted to a number.

Solution 4 - Javascript

There is no dedicated string concatenation operator in JavaScript**. The addition operator + performs either string concatenation or addition, depending on the type of operands:

"1" +  1  // "11"
 1  + "1" // "11"
 1  +  1  // 2

There is no opposite of concatenation (I think) and the subtraction operator - only performs subtraction regardless of the type of operands:

"1" -  1  // 0
 1  - "1" // 0
 1  -  1  // 0
"a" -  1  // NaN

** The . operator in PHP and & operator in VB are dedicated string concatenation operators.

Solution 5 - Javascript

+ is both an addition operator for numeric variables, and a concatenation operator for strings.

Whenever there's a string after a +, Javascript will choose to use the + as a concatenation operator and convert (typed) as many terms as possible around the string so it can concatenate them. That's just the behaviour of Javascript. (If you tried console.log(23 + 2 + "." + 1 + 5 + "02" + 02);, you'll get the result 25.15022. The number 02 was typed into the string 2 before being concatenated.

- can only be a subtraction operator, so when given a string, it will implicitly change the type of the string "1" into a numeric 1; if it didn't do that, there's no way "1" - 1 would make sense. If you tried console.log(23 + 2 + 1 + 5 - "02" + 03); you'll get 32 - the string 02 gets converted into the number 2. The term after the - must be able to be converted into a number; if you tried console.log(23 - 2 - "." - 1 - 5 - 02 - "02"); you'll get NaN returned.

More importantly, if you tried console.log(23 + 2 + "." + 1 + 5 - "02" + 03);, it will output 26.15, where everything before - was treated as a string (because it contains a string ".", and then the term after the - is treated as a number.

Solution 6 - Javascript

According to the standard EcmaScript 262. The + and - operators behave differently when strings are involved. The first converts every value to a string. The second converts every value to a number.

From the standard:

> If Type(lprim) is String or Type(rprim) is String, then Return the > String that is the result of concatenating ToString(lprim) followed by > ToString(rprim)

This rules implies that if in the expression there is a string value, all values involved in the + operation are converted to a string. In JavaScript when the + operator is used with strings, it concatenates them. This is why console.log("5"+1) returns "51". 1 is converted to a string and then, "5" + "1" are concatenated together.

Nevertheless, the above rule doesn't apply for the - operator. When you are using a - all values are converted to numbers according to the Standard (see below). Therefore, in this case, "5" is converted to 5 and then 1 is subtracted.

From the standard:

> 5 Let lnum be ToNumber(lval). > > 6 Let rnum be ToNumber(rval).


      Operator definition from the standard EcmaScript 262.

Operator + : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.1 Operator + definition

Operator - : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2 Operator - definition

Solution 7 - Javascript

Using plus and a string "" you basically return a string because you are performing a concatenation:

typeof ("" + 1 + 0)  // string
typeof (1 + 0)  // number

When using - instead you convert to a number as string concatenation is possible:

typeof ("" - 1 + 0) // number

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionNirgnView Question on Stackoverflow
Solution 1 - JavascriptBernhard HofmannView Answer on Stackoverflow
Solution 2 - JavascriptNiet the Dark AbsolView Answer on Stackoverflow
Solution 3 - JavascriptYury TarabankoView Answer on Stackoverflow
Solution 4 - JavascriptSalman AView Answer on Stackoverflow
Solution 5 - JavascriptdayuloliView Answer on Stackoverflow
Solution 6 - JavascriptGiuseppe PesView Answer on Stackoverflow
Solution 7 - JavascriptGibboKView Answer on Stackoverflow