Reputation: 229321
JavaScript does funky automatic conversions with objects:
var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));
will print:
4040
40140
120
This is because +, if any of the arguments are objects/strings, will try to convert all the arguments to strings then concatenate them. If all arguments are numbers, it adds them together. * and unary + convert objects to numbers using toString (as well as valueOf, not shown here).
What does JavaScript do for the ++ operator?
Upvotes: 1
Views: 297
Reputation: 49582
From ECMAScript Language Specification
11.3 Postfix Expressions
Syntax
PostfixExpression :
- LeftHandSideExpression
- LeftHandSideExpression [no LineTerminator here] ++
- LeftHandSideExpression [no LineTerminator here] --
11.3.1 Postfix Increment Operator
The production PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ is evaluated as follows:
- Evaluate LeftHandSideExpression.
- Call GetValue(Result(1)).
- Call ToNumber(Result(2)).
- Add the value 1 to Result(3), using the same rules as for the + operator (section 11.6.3).
- Call PutValue(Result(1), Result(4)).
- Return Result(3).
This is pseudo javascript code of how postInc works:
function postInc(a) {
var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
a = x + 1;
return x;
}
Edit: As mikesamuel said: it's not parseInt. Updated to reflect that.
Upvotes: 4
Reputation: 36773
The ++
operator does a "toNumber" conversion (basically a combination of type rules and the valueOf function). Basically for any resolve expression
resolveExpression++
The steps taken by the JS engine are
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
For non-atomic resolve expressions, eg. base.resolve++
or base["resolve"]++
, etc. base
is resolved only once and then reused. In any sane case this is irrelevant, however it's important if the value being incremented is an object with a valueOf implementation that changes the base object.
eg.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;
Upvotes: 1
Reputation: 229321
The following code illustrates this well:
var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);
The output is:
object
number
object
number
41
number
Unary plus converts the object to a number and doesn't modify it. a++ first converts the object to a number, then returns that number, and then increments the number, storing the value in a.
This is opposed to another possible solution, where a++ would first return the object, and then do the conversion to a number and incrementation.
Upvotes: 3