How does JavaScript handle the ++ operator?
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 arguments to strings and then concatenate them. If all arguments are numbers, they concatenate them. * and unary + convert objects to numbers using toString (and also the Of value, not shown here).
What does JavaScript do for the ++ operator?
source to share
From ECMAScript Language Specification
11.3 Postfix Expressions
Syntax
PostfixExpression:
- Left-handed expression
- LeftHandSideExpression [no LineTerminator here] ++
- LeftHandSideExpression [no LineTerminator here] -
11.3.1 Postfix Home Operator
PostfixExpression derivative: LeftHandSideExpression [no LineTerminator here] ++ evaluates as follows:
- Calculate the LeftHandSideExpression value.
- 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).
- Calling PutValue (Result (1), Result (4)).
- Return result (3).
This is pseudo javascript 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 this.
source to share
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);
Output:
object
number
object
number
41
number
Unary plus converts the object to a number and does not change it. a ++ first converts the object to a number, then returns that number , and then increments the number, storing the value in a.
This contradicts another possible solution where ++ first returns an object and then does the conversion to number and increment.
source to share
The operator ++
performs the "toNumber" conversion (basically a combination of type rules and valueOf function). Basically for any permission expression
resolveExpression++
The steps taken by the JS engine are
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
For non-atomic permission expressions, eg. base.resolve++
or base["resolve"]++
etc. base
is allowed only once and then reused. It doesn't matter in any sane case, however it is important that the value increment is an object with an implementation of valueOf that modifies the underlying object.
eg.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;
source to share