From EcmaScript standard:
11.4.4 Prefix Increment Operator 
The production UnaryExpression : ++ UnaryExpression is evaluated as follows: 
- Let expr be the result of evaluating UnaryExpression. 
- Throw a SyntaxError exception if the following conditions are all true: �
  
- Type(expr) is Reference is true 
- IsStrictReference(expr) is true 
- Type(GetBase(expr)) is Environment Record 
- GetReferencedName(expr) is either "eval" or "arguments" 
 
- Let oldValue be ToNumber(GetValue(expr)). 
- Let newValue be the result of adding the value 1 to oldValue, using the same rules as for the + operator (see 11.6.3). 
- Call PutValue(expr, newValue). 
- Return newValue. 
and
11.13.2 Compound Assignment ( op= ) 
The production AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression, where AssignmentOperator is @= and @ represents one of the operators indicated above, is evaluated as follows: 
- Let lref be the result of evaluating LeftHandSideExpression. 
- Let lval be GetValue(lref). 
- Let rref be the result of evaluating AssignmentExpression. 
- Let rval be GetValue(rref). 
- Let r be the result of applying operator @ to lval and rval. 
- Throw a SyntaxError exception if the following conditions are all true: 
  
- Type(lref) is Reference is true 
- IsStrictReference(lref) is true 
- Type(GetBase(lref)) is Environment Record 
- GetReferencedName(lref) is either "eval" or "arguments" 
 
- Call PutValue(lref, r)
Thus, var i = 0; i += ++i is:
i = 0;
lvalue = value(i), which is 0;
rvalue = value(++i), which is: increment i, then value of i (1);
thus, rvalue = 1;
i = lvalue (0) + rvalue (1), which is 1.
Completely according to spec.
However, in C++, this is specifically defined to be undefined behaviour, thus on a different compiler you might also get 1. Or 99. Or it could set your computer on fire. All of those would be standard-compliant compilers. Thus, most people will recommend you only use pre/post-incremented variable once in a statement.