JavaScript和PHP的赋值运算符为什么会有不同结果?

6

JavaScript 代码:

var a = 1, b = 2;
a = b + (b = a) * 0;
// result a = 2, b = 1;

PHP代码1:

$a = 1;
$b = 2;
$a = $b + ($b = $a) * 0;
// result $a = 1, $b = 1;

PHP代码2:

$a = 1;
$b = 2;
$a = (int)$b + ($b = $a) * 0;
// result $a = 2, $b = 1;

是什么导致了PHP和JavaScript的赋值运算符之间的差异?

这与运算符优先级有关吗?

我想知道原因是什么。谢谢!


我怀疑两种语言都没有定义如果在同一表达式中给变量赋值并使用它会发生什么。但是如果它们确实这样做了,那么区别就在于操作顺序。 - Barmar
4
你为什么要写这样复杂的代码呢?不应该在表达式中混合赋值,这是没有借口的。 - Barmar
$a = 1; $b = 2; $a = $b + (($b = $a) * 0); $a赋值为1; $b赋值为2; $a的值为$b加上(($b=$a)*0); - mehulmpt
我认为这不是一个“现实生活”编程问题。投票关闭。最好在程序员上发布。 - Ryan
2个回答

4

不,运算符优先级不影响计算顺序,因此在复杂的计算中使用赋值重用计算结果是未定义的。

来自PHP手册:

运算符优先级和结合性仅决定表达式的分组方式,它们不指定表达式求值的顺序。 PHP通常不指定表达式的求值顺序,并且应该避免假设特定的求值顺序的代码,因为行为可能会因PHP版本或周围代码而改变。

简而言之,$b + ($b = $a)的输出是未定义的,因为分组覆盖了优先级,并且没有以任何方式强制执行赋值发生在获取加法左操作数之前还是之后。运算符的优先级已经明确定义,但是执行/评估顺序是未定义的


1
这就是为什么我们在生活中不能拥有任何好东西的原因!!!PHP怎么可能不保证执行顺序。现在我更加正式地讨厌PHP了! - Rafael
感谢您的热情回应。 - by_phper

1

为了从JavaScript的角度补充@NielsKeurentjes的答案:

(与PHP相比) JavaScript指定操作的顺序(操作数从左到右进行评估),这使得它按预期工作。

来自ECMAScript规范:

生产AdditiveExpression:AdditiveExpression + MultiplicativeExpression的评估如下:

  1. lref成为评估AdditiveExpression的结果。
  2. lval为GetValue(lref)。
  3. rref成为评估MultiplicativeExpression的结果。
  4. rvalGetValue(rref)

很好的发现,我找不到规范的这一部分来补充我的答案。+1 - Niels Keurentjes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接