Javascript中的预增量 [英] Pre increment in Javascript

查看:96
本文介绍了Javascript中的预增量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚在Javascript中遇到了关于预增量的'功能'。在我使用的所有其他语言中,它就像我认为的那样。例如。在C ++中:

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.
}

所以, ++ i 不复制变量,因此输出为2.

So, ++i doesn't make copy of the variable, hence the output is 2.

与PHP相同:

<?php

$i = 0;

$i += ++$i;

echo $i; // Outputs 2.

但是,在Javascript中:

However, in Javascript:

var i = 0;

i += ++i;

console.log(i); // Outputs 1.

所以在Javascript中它看起来像是 i 并且不引用该变量。这是故意的,如果是,为什么?

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?

推荐答案

来自EcmaScript标准:

From EcmaScript standard:


11.4.4前缀增量运算符

11.4.4 Prefix Increment Operator

生产UnaryExpression:++ UnaryExpression的计算方法如下:

The production UnaryExpression : ++ UnaryExpression is evaluated as follows:


  1. 让expr成为评估UnaryExpression的结果。

  2. 如果满足以下条件,则抛出一个SyntaxError异常:

    • Type(expr)为Reference is true

    • IsStrictReference(expr)为真

    • 类型(GetBase(expr))是环境记录

    • GetReferencedName(expr)是eval或arguments

  1. Let expr be the result of evaluating UnaryExpression.
  2. 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"



11.13.2复合赋值(op =)

11.13.2 Compound Assignment ( op= )

生产AssignmentExpression:LeftHandSideExpression AssignmentOperator AssignmentExpression,其中AssignmentOperator是@ =和@代表上面指出的一个运算符,评估如下:

The production AssignmentExpression : LeftHandSideExpression AssignmentOperator AssignmentExpression, where AssignmentOperator is @= and @ represents one of the operators indicated above, is evaluated as follows:


  1. 让lref成为评估LeftHandSideExpression的结果。

  2. 让lval成为GetValue(lref)。

  3. 让rref成为评估AssignmentExpression的结果。

  4. 让rval为GetValue(rref)。

  5. 设r是将operator @应用于lval和rval的结果。

  6. 如果以下条件都为真,则抛出一个SyntaxError异常:

    • Type(lref)is Reference is true

    • IsStrictReference(lref)为真

    • 类型(GetBase(lref))是环境记录

    • GetReferencedName(lref)要么是eval或arguments

  1. Let lref be the result of evaluating LeftHandSideExpression.
  2. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating AssignmentExpression.
  4. Let rval be GetValue(rref).
  5. Let r be the result of applying operator @ to lval and rval.
  6. 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"


因此, 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.

完全按照但是,在C ++中,这被明确定义为未定义的行为,因此在不同的编译器上你也可能得到1.或99.或者它可以设置为规范。

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.

这篇关于Javascript中的预增量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆