赋值和变量的自增问题
var i=1;
i=i++;
alert(i);
为什么i=1?
1.左边i先赋值给右边,i=1;
2.i++,之后i不就是2了吗?就算不赋值,也应该是2额。。
Answers
var i=1;
i=i++;
alert(i);
“=”是将“=”右边的表达式的值赋给“=”左边的变量
所以先执行i++这个表达式,
i++先返回 i 的初始值1
,再进行 i +1 运算。i++运算完后 i = 2;
计算完“=”右边的表达式之后,就将
表达式的值 1
赋给了“=”左边的变量i;
因此 i = 1;
i=i++这个过程中i被赋了两次值
第一次是计算 i++ 的时候 此时i=2 (i++返回值为1)
第二次是计算 i = (i++的值1) 的时候此时i = 1;
注:本人是新手,上面是我对i=i++的理解,如果那里不对,请指出,谢谢!!!
首先,赋值运算符
=
是把右边的值赋给左边。
然后,自增运算符“++”放在变量后面即
i++
的意思是
先使用变量,再将变量i的值加1
。如果放在变量前面即
++i
的意思是
先将变量i的值加1,再使用变量
举例:
var i = 1;
var j = i++;
alert(j); // 1,先为j赋i的值1,
alert(i); // 2,然后执行++,i的值加1,2
那么为什么你的代码结果i是1呢?
var i = 1;
i = i++;
alert(i); // 1
这是因为
js中,变量的值是不能重新赋值的。重新为一个变量赋值,会申请一个新变量,为其赋值并销毁原来的变量。
本例中,
i = i++
其实是先在内存中申请一个空间,里面填充1(i的值),然后让变量i指向这块内存空间,而存放这i++得来的2的那块内存,已经索引不到了,一会儿其所占内存就被回收了
=
++
这些本质上都是运算符,地位是平等的。
这确实是运算符优先级的问题,但曲奇芒果说的应该有毛病。
因为赋值运算符
=
的优先级是最低的,是最后做运算的,而不是先做a=b运算。赋值运算符
=
作为operator,它的两个operand分别是左边的variable i和右边的一个expression
i++
,这次运算是将这个表达式的值赋给变量i,是最后操作的。
++后置运算符的效果是
returns the value before incrementing
, 变量i在这次运算确实被赋值为2,但是这个表达式的值是1,此后,由于优先级最低的运算最后运行,又将这个1赋值给了变量i,所以最终i的值为1
ECMAScript® Language Specification
11.13.1 Simple Assignment ( = )
The production AssignmentExpression : LeftHandSideExpression =
AssignmentExpression is evaluated as follows:Let lref be the result of evaluating LeftHandSideExpression. Let rref
be the result of evaluating AssignmentExpression. Let rval be
GetValue(rref). 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, rval). Return rval. NOTE When an assignment occurs
within strict mode code, its LeftHandSide must not evaluate to an
unresolvable reference. If it does a ReferenceError exception is
thrown upon assignment. The LeftHandSide also may not be a reference
to a data property with the attribute value {[[Writable]]:false}, to
an accessor property with the attribute value {[[Set]]:undefined}, nor
to a non-existent property of an object whose [[Extensible]] internal
property has the value false. In these cases a TypeError exception is
thrown.
注意這兩句:
Let rval be GetValue(rref).
Call PutValue(lref, rval).
也就是說,首先執行 i++,此時 i 被賦值 2,並返回 1,然後再賦值 1 給 i,最終 i 爲 1。
簡單地說,
javascript
var i = 1; i = i++;
等價於
javascript
var i, temp; // temp is "rval", which may not be an actual variable. i = 1; temp = i; i = i + 1; i = temp;
當然
也可以用一個簡單的實驗看出:
javascript
var i = 1; i = (i++, i); // 2
可見 i++ 賦值 i 必定早於 i = (...) 的賦值。
上面的內容等價於:
javascript
var i, temp; // temp is "rval", which may not be an actual variable. i = 1; temp = i; i = i + 1; i = i;
等價於
i = ++i
; (實際上引擎可能會省略 temp (rval) 的賦值)