I've just encountered a 'feature' in Javascript regarding pre-increments. In all other languages I've used, it goes like I thought it would. E.g. in C++:
#include <iostream>
int main()
{
int i = 0;
i += ++i;
std::cout << i << std::endl; // Outputs 2.
}
So, ++i
doesn't make copy of the variable, hence the output is 2.
Same in PHP:
<?php
$i = 0;
$i += ++$i;
echo $i; // Outputs 2.
However, in Javascript:
var i = 0;
i += ++i;
console.log(i); // Outputs 1.
So it looks like that in Javascript, it makes copy of i
and doesn't reference the variable. Is this intentional and if yes, why?
++i returns the value of i after it has been incremented. i++ returns the value of i before incrementing. When the ++ comes before its operand it is called the "pre-increment" operator, and when it comes after it is called the "post-increment" operator.
The increment operator ( ++ ) increments (adds one to) its operand and returns the value before or after the increment, depending on where the operator is placed.
JavaScript has an even more succinct syntax to increment a number by 1. The increment operator ( ++ ) increments its operand by 1 ; that is, it adds 1 to the existing value.
++ increases the integer by one and += increases the integer by the number of your choice.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With