Javascript ++ vs +=1 - javascript

var a = "ab";
var b = "ab";
a+=1; // "ab1"
b++; // "NaN"
(Tested on chrome's V8)
Can someone explain why the results are different based on the internal atomic actions of the ++ arithmetic operator and the += assignment operator with argument 1

++ converts to number, and then increments, += with a String concatenates.
From the spec:
11.3.1 Postfix Increment Operator
...
3. Let oldValue be ToNumber(GetValue(lhs)).
4. Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 11.6.3).
For the a+=1 case, if you add a number to a string or the other way around the number gets converted to a string:
11.6.1 The Addition operator ( + )
...
7. If Type(lprim) is String or Type(rprim) is String, then
a. 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).

++ tries to increment a Number (if it's not a number, this will fail - resulting in NaN)
+= is concatenation, in this case the JavaScript engine figures out that one side is a string, so they're both concatenated as strings.
They're different because they're different operations, ++ is specifically an arithmetic operator, where as += is a more general assignment operator that behaves differently based on the data type - specifically, string has its own implementation.

That's because the + operator in javascript is both the mathematical + and the string concatenation operator, while the ++ is always a mathematical operator.
So, when you have:
string = string + number;
the number is converted to string and concatenated to the first string.
When you have
string++
you will convert the string to a number, getting NaN, and then add one to that - getting still, NaN.

Related

Why string + number = string but for other operators it does arthemitic operation in javascript [duplicate]

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?
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.
+ 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...).
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.
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.
+ 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.
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 - : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2
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

Why does implicit coercion for addition always produce a string?

If only the second operand in addition is a string then the output is a string:
let a = 1 + '2';
console.log(typeof a); // string
And if, instead, only the first operand is a string, then the output is still a string:
let b = '1' + 2;
console.log(typeof b); // string
I was guessing that there would be some kind of argument precedence. Is there a reason why this mathematical function defaults to a non-numerical output with mixed-type arguments?
As it is often the case, the answer is "because the spec says so". More specifically, section 11.6.1 The Addition operator ( + ).
On step 7, you can read
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)
In other words, if at least one of the operands is a string, the result will be the concatenation of the string representation of both operands.
There is precedence in a way, because if both operands were functions the left one would be evaluated before the right one, but it doesn't matter for the algorithm that decides if the + operation should return a string or a number.
Note: I referred to the ECMAScript 5 spec but you can find something equivalent in the newer versions.
When a single operator is part of an expression, the expression is performed left to right, but in JavaScript, if any one of the operands used with the + operator is a string, the other one will be converted to a string - it doesn't matter which one. This is because the + operation can mean string addition (concatenation) or mathematical addition. When one operand is a string, the JavaScript runtime correctly assumes that the + should mean string addition because the string could contain a non-numeric value and doing math with non-numeric values is problematic, to say the least.
You would need to do a conversion on the non-string before the concatenation occurs. This can be done in a number of ways:
console.log(1 + +"2"); // prepending a + to a string attempts to convert to a number
// Note that with all of the following there is a nested function call being performed
// and these functions take an argument, which requires () for the argument to be passed.
// Because of the nested (), that function call is performed first and the result of the
// function call is returned to the expression.
console.log(1 + parseInt("2.4")); // parse the integer portion of the string into a number
console.log(1 + parseFloat("2.4")); // parse the floating point number in the string into a number
console.log(1 + Number("2")); // convert the string into a number
The basic operator precedence is:
Parenthesis
Exponents
Multiplication
Division
Addition
Subtraction
So, in the following examples, you can see that happening:
// Here, the order of operations will be:
// Parenthesis: (2/2) === 1
// Multiplication: 10 * 1 === 10
// Addition: 1 + 10 === 11
// Subtraction: 11 - 3 === 8
console.log(1 + 10 * (2 / 2) - 3);
// But here, because of the string, the order of operations will be:
// Parenthesis: (2/2) === 1
// Multiplication: 10 * 1 === 10
// Addition: "1" + 10 === "110" (one operand is a string, so the other converts to a string)
// Subtraction: "110" - 3 === 107 (the string "110" will be implicitly converted to a number
// becuase the - sign only has one meaning in a mathmatical
// expression)
console.log("1" + 10 * (2 / 2) - 3);
See JavaScript Operator Precedence for a full list of operators and their precedence.
See Unary + Operator for how it is used to convert to a number.
Also note that we're not talking about "arguments" here (an argument is what is passed to a method or function). These are operands in an expression with operators.

Unexpected result when using the subtraction operator with string values in Javascript [duplicate]

This question already has answers here:
Why does JavaScript handle the plus and minus operators between strings and numbers differently?
(7 answers)
Closed 5 years ago.
Why does Javascript give an output of 0 when I use the odd operator?
What is the difference between subtraction and addition with a string?
var x = 1;
console.log(x+'1') // Outputs 11
console.log(x-'1') // Outputs 0 -- but why?
So how can I do mathematical calculations?
The + operator has one of two three meanings in javascript. The first is to add numbers, the second is to concatenate strings. When you do 1 + '1' or '1' + 1 the operator will convert one operand that is not a string to a string first, because one other operand is already evaluated to be a string. The - operator on the other hand has just one purpose, which is to subtract the right operand from the left operand. This is a math operation, and so the JS engine will try to convert both operands to numbers, if they are of any other datatype.
I'm not sure though why typecasting to strings appears to have precedence over typecasting to numbers, but it obviously does.
(It seems to me the most likely that this is a pure specification decision rather than the result of other language mechanics.)
If you want to make sure that the + operator acts as an addition operator, you can explicitly cast values to a number first. Although javascript does not technically distinguish between integers and floats, two functions exist to convert other datatypes to their number equivalents: parseInt() and parseFloat() respectively:
const x = 10;
const result = x + parseInt('1'); // 11
const y = 5;
const result2 = y + parseFloat('1.5'); // 6.5
const result3 = y + parseInt('1.5'); // 6
Edit
As jcaron states in the comment below, the + operator has a third meaning in the form of an unary + operator. If + only has a right operand, it will try to convert its value to a number almost equivalent as how parseFloat does it:
+ '1'; // returns 1
+ '1.5'; // returns 1.5
// In the context of the previous example:
const y = 5;
const result2 = y + +'1.5'; // 6.5
Dhe difference with parseFloat is that parseFloat will create a substring of the source string to the point where that substring would become an invalid numeric, whereas unary + will always take the entire string as its input:
parseFloat('1.5no-longer-valid'); // 1.5
+ '1.5no-longer-valid'; // NaN
That is because + is a concatenation operator. So javascript considers it to be a concatenation operator rather than a mathematical operator.But it is not the case with / ,* ,/ etc.
This happens because + its also used to concatenate strings. Then, JS always will find the better way to make the correct typecasts basing on types. In this case, the x+'1' operation, will be identified as string type + string type.
Otherwise, x-'1', will become int type - int type.
If you want to work with specific types, try to use type cast conversions, link here.

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

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?
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.
+ 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...).
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.
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.
+ 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.
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 - : http://www.ecma-international.org/ecma-262/5.1/#sec-11.6.2
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

Javascript + operator vs - operator

I am puzzled by this snippet:
var n1 = 5-"4";
var n2 = 5+"4";
alert(n1);
alert(n2);
​I understand that n1 is 1. That is because a minus operator would convert the string "4" into number and subtract it from 5.
But why do we get 54 in case of + operator?
Can someone explain this difference between + and = operators to me?
By type conversion any + expression, that contains a strings, will result in a string. Thus all operands (in your case 5) will be converted to a string, before executing the concatenation.
- on the other hand is just an arithmetic operand, thus "4" is converted to an integer and the calculation is performed as you expect.
It's because in n2, + is being treated as concatenation, not addition. So 5 is converted to the string "5" and "4" is concatenated, giving "54".
When there's a string in either side of +, the + will be considered as a string concatenating operator, the other side will be converted to string and then do the concatenating.
And be careful of something like 1+2+'3', the result is '33' rather than '123'.
- operator has only one meaning - numbers subtraction (or negation and in that case, also conversion to number). In case of + operator, however, there are two: number addition and strings concatenation. When one of the operands of + operator is a string it does string concatenation instead of numbers addition.
The entire process is a bit more complicated than that though and involves an algorithm that you can learn a bit more here, for example.
The + operator is also a string operator. Quite every basic type variable in javascript can be interpreted also in its string representation. You are just attaching 5 to 4 getting 54.
The - operator is not a string operator so the compiler tries to interpret "4" as a number, thus getting 1
Javascript takes 5 as a number and "4" as string.
The javascript + operator use to concat two things.
If you want to addition please use parseInt.
var n1 = 5-"4";
var n2 = parseInt(5)+parseInt("4");
alert(n1);
alert(n2);

Categories