admin管理员组文章数量:1317356
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'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?
- Maybe not an explanation, or even a solution, but certainly a good read: stackoverflow./questions/971312/… – emerson.marini Commented May 29, 2014 at 10:06
- In C++, this isn't even meaningful. it's undefined behavior. – The Paramagnetic Croissant Commented May 29, 2014 at 10:08
- Another good read: javascript.about./od/hintsandtips/a/… – emerson.marini Commented May 29, 2014 at 10:11
- stackoverflow./questions/1546981/… – Abdennour TOUMI Commented May 29, 2014 at 10:23
2 Answers
Reset to default 7From 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 piler you might also get 1. Or 99. Or it could set your puter on fire. All of those would be standard-pliant pilers. Thus, most people will remend you only use pre/post-incremented variable once in a statement.
I believe this is because javascript see's var i = 0; i += ++i;
as this:
var i = 0;
++i = 1;
i += 1;
It's because the ++i
turns i into 1 before performing +=
, so it's 0 + 1 = 1
In fact, the more I think about it, why would it do anything else?
There are two assignments taking place, and one has to be done before the other. So the two options would be either:
- do ++i first, and make it i = i + 1 where i starts at 0 and equates to 1
or
- do the += first, and make it i = 0 + (++i) which would also equate to 1
本文标签: Pre increment in JavascriptStack Overflow
版权声明:本文标题:Pre increment in Javascript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742021045a2414678.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论