nha*_*123 11 javascript pre-increment
我刚刚在Javascript中遇到了关于预增量的'功能'.在我使用的所有其他语言中,它就像我认为的那样.例如在C++中:
#include <iostream>
int main()
{
int i = 0;
i += ++i;
std::cout << i << std::endl; // Outputs 2.
}Run Code Online (Sandbox Code Playgroud)
因此,++i不会复制变量,因此输出为2.
在PHP中相同:
<?php
$i = 0;
$i += ++$i;
echo $i; // Outputs 2.
Run Code Online (Sandbox Code Playgroud)
但是,在Javascript中:
var i = 0;
i += ++i;
console.log(i); // Outputs 1.
Run Code Online (Sandbox Code Playgroud)
所以它看起来像在Javascript中,它复制i并且不引用变量.这是故意的,如果是,为什么?
来自EcmaScript标准:
11.4.4前缀增量运算符
生产UnaryExpression:++ UnaryExpression的计算方法如下:
- 设expr是评估UnaryExpression的结果.
- 如果满足以下条件,则抛出SyntaxError异常:
- Type(expr)是Reference为true
- IsStrictReference(expr)是真的
- Type(GetBase(expr))是环境记录
- GetReferencedName(expr)是"eval"或"arguments"
- 设oldValue为ToNumber(GetValue(expr)).
- 设newval是将值1添加到oldValue的结果,使用与+运算符相同的规则(见11.6.3).
- 调用PutValue(expr,newValue).
- 返回newValue.
和
11.13.2复合赋值(op =)
生产AssignmentExpression:LeftHandSideExpression AssignmentOperator AssignmentExpression,其中AssignmentOperator是@ =和@代表上面指出的一个运算符,评估如下:
- 让lref成为评估LeftHandSideExpression的结果.
- 设lval为GetValue(lref).
- 让rref成为评估AssignmentExpression的结果.
- 设rval为GetValue(rref).
- 设r是将operator @应用于lval和rval的结果.
- 如果满足以下条件,则抛出SyntaxError异常:
- Type(lref)是Reference为true
- IsStrictReference(lref)是真的
- Type(GetBase(lref))是环境记录
- GetReferencedName(lref)是"eval"或"arguments"
- 调用PutValue(lref,r)
因此,var i = 0; i += ++i是:
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.
Run Code Online (Sandbox Code Playgroud)
完全按照规范.
但是,在C++中,这被明确定义为未定义的行为,因此在不同的编译器上,您可能也会获得1.或99.或者它可能会使您的计算机着火.所有这些都是符合标准的编译器.因此,大多数人会建议您只在声明中使用一次/后递增变量.
| 归档时间: |
|
| 查看次数: |
2483 次 |
| 最近记录: |