代码之家  ›  专栏  ›  技术社区  ›  Matthew Daly

为什么JavaScript的后缀表示法不同于C和Perl?

  •  6
  • Matthew Daly  · 技术社区  · 15 年前

    我现在正在学习JavaScript考试。我对C和Perl也有一些了解,所以我熟悉这三种语言的前缀和后缀表示法。

    我为它做了一个在线实践考试,我犯的一个错误是评估以下代码:

    var x = 10;
    x += x--;
    

    现在,我认为它的值是19,因为它是10+10,然后减去1得到9。但我得到的反馈是,这是错误的,实际上评估为20。我觉得这听起来有点可疑,所以我在一个HTML文档中测试了它,结果又是20个。然后我尝试使用C和Perl中的等价物,两种方法的计算结果都是19。

    有人能向我解释为什么当其他语言将答案评估为19时,javascript将其评估为20?我从测试中得到的答案对我来说不太清楚:

    增量++ 和减量——可以放置运算符 在操作数之前或之后。如果递增或递减 运算符放在操作数之前,操作立即发生。 如果递增或递减运算符放在操作数之后,则 直到下一次 在程序中访问操作数。因此,表达式x+=x——等于x=x。+ 10,其值为20。

    4 回复  |  直到 15 年前
        1
  •  6
  •   Christoph    15 年前

    扩展语句

    x += x--;
    

    到更详细的JS代码

    x = x + (function(){ var tmp = x; x = x - 1; return tmp; })();
    

    结果非常有意义,因为它将评估

    x = 10 + (function(){ var tmp = 10; x = 10 - 1; return tmp; })();
    

    哪一个是20。请记住,JS从左到右计算表达式,包括复合赋值,即 x 在执行前缓存 x-- .


    您也可以这样想:假设从左到右的评估顺序,JS将赋值解析为

    x := x + x--
    

    而Perl将使用

    x := x-- + x
    

    我看不出支持或反对这两种选择的任何有说服力的论据,所以不同语言的行为不同只是运气不好。

        2
  •  3
  •   Patrick    15 年前

    在C/C++中,每个变量只能在每一个语句中改变一次(我认为确切的术语是:在两个代码点之间只有一次,但我不确定)。

    如果你写

    x += x--;
    

    您将更改x的值两次:

    • 您正在使用postfix—运算符递减x
    • 您正在使用分配设置x的值

    尽管您可以编写这个代码,编译器也不会对此抱怨(不确定,您可能希望检查不同的警告级别),但结果是未定义的,并且每个编译器中的结果都可能不同。

        3
  •  1
  •   Russ Cam    15 年前

    基本上,x的值在赋值后会减少。这个例子可能会更清楚(在Firebug控制台中运行)

    var x = y =10;    
    x += y--;        
    console.log(x , y); // outputs 20 9
    
        4
  •  1
  •   Anon.    15 年前

    在C中,行

    x += x--;
    

    是未定义的行为。似乎您的特定编译器将其视为:

    oldx = x--;
    x = x + oldx
    

    然而,ECMAScript规范 指定 op= -它得到左手边的值 之前 评估右侧。

    所以它相当于:

    oldx = x--;
    x = oldx + oldx