JS vs PHP:与逻辑或运算符一起使用时,赋值运算符优先级 [英] JS vs PHP: assignment operator precedence when used with logical-or

查看:116
本文介绍了JS vs PHP:与逻辑或运算符一起使用时,赋值运算符优先级的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(PHP具有||OR.JS仅具有||.)

(PHP has || and OR. JS only has ||.)

JS .根据 MDN ||的优先级高于=.所以这行不通:

JS. According to MDN || has higher precedence than =. So this doesn't work:

a || a = 1;

因为它的评估为:

(a || a) = 1;

这将导致分配中的左侧无效".我明白那个.那是有道理的.

which results in an "Invalid left-hand side in assignment". I understand that. That makes sense.

PHP.根据 PHP.net 对于PHP:||=之前的工作方式相同.但是,我一直都在使用它:

PHP. According to PHP.net it works the same for PHP: || before =. However, I use this all the time:

$a || $a = 1;

为什么它可以在PHP中运行?最重要的是:PHP的OR优先级低于=,因此它们不应该这样做:

Why does it work in PHP?? And to top it off: PHP's OR has lower precedence than =, so these shouldn't do the same:

$a || $a = 1;
$a OR $a = 1;

但是他们确实... https://3v4l.org/UWXMd

but they do... https://3v4l.org/UWXMd

我认为JS的||根据MDN的表工作,而PHP的OR类似于PHP的表,但PHP的||不应像它那样工作.

I think JS' || works according to MDN's table, and PHP's OR works like PHP's table, but PHP's || shouldn't work like it does.

这是另一个怪异的PHP怪癖吗?

Is this yet another weird PHP quirk?

手册中也提到了这一点:

The manual also mentions this:

尽管=的优先级低于大多数其他运算符,但PHP仍将允许类似于以下内容的表达式:if (!$a = foo()),在这种情况下,foo()的返回值将放入$a.

Although = has a lower precedence than most other operators, PHP will still allow expressions similar to the following: if (!$a = foo()), in which case the return value of foo() is put into $a.

优先级表指示PHP应该评估(!$a) = foo(),这没有意义并且应该失败,但是PHP将其评估为!($a = foo()),因为它喜欢异常.

The precedence table dictates PHP should evaluate (!$a) = foo(), which makes no sense and should fail, but PHP evaluates it as !($a = foo()), because it loves exceptions.

后续问题:您认为if ( $d = $c && $e = $b && $f = $a )是什么? https://3v4l.org/3P2hN 我听不懂...我确实了解第二和第三个情况(使用and),只是没有发生在第一个情况中.

Follow-up question: What do you think if ( $d = $c && $e = $b && $f = $a ) does? https://3v4l.org/3P2hN I don't get it... I do understand the second and third case (with and), just not what happens in the first.

推荐答案

根据

According to zend_language_parser.y the code is parsed equivalently to $a || ($a = 1) and $a or ($a = 1) in each case, respectively.

正如melpomene总结的那样,赋值产生是 not 在表达式上的后缀二元运算符;相对而言,分配运算符是受限产品,其中左侧必须variable产品.

As summarized by melpomene, the assignment productions are not infix binary operators over expressions; rather assignment operators are restricted productions where the left-hand side must be a variable production.

每个借用的报价:

因此,PHP以唯一可能的方式解析表达式.

Thus PHP parses the expression in the only possible way..

有关优先顺序的文档正确.适用的地方.

The documentation is correct about the precedence .. where it applies.

因此,$a || $a = 1遵循以下(反向)的结果:

Thus $a || $a = 1 follows the (reversed) productions of:

variable "||" variable "=" expr
variable "||" expr_without_variable
expr "||" expr
expr

!$a = foo()的情况与之类似,并且在遵循(反转)后会被解析为!($a = foo()):

The case of !$a = foo() is similar and is parsed as !($a = foo()) after following the (reversed) productions:

"!" variable "=" expr
"!" expr_without_variable
"!" expr                 
expr

现在,$d = $c && $e = $b && $f = $a怎么样?即使&& 确实的优先级高于分配,它也不会被解析为($d = $c) && ...它实际上被解析为$d = ($c && ($e = ..)),依此类推,由精明的读者完成.

Now, how about $d = $c && $e = $b && $f = $a? It is not parsed as ($d = $c) && .. even though the && does have a higher precedence than the assignment. It is actually parsed as $d = ($c && ($e = ..)) and so on, to be completed by the astute reader.

虽然可能不会引起人们的注意,但这种差异能够产生不同的结果:

While it might not be casually noticed, this difference is capable of producing varying results:

$a = (($c = 1) && ($d = 0));
var_dump($a, $c, $d);         // => false, 1, 0

$b = ($e = 1 && $f = 0);      // => $b = ($e = (1 && ($f = 0)));
var_dump($b, $e, $f);         // => false, false, 0

因此,在将赋值运算符与优先级更高的运算符混合使用时,通常应使用括号,尤其是当这样的结果可能不清楚时.

Parenthesis should thus generally be used when mixing assignment operators with operators of higher precedence, especially when the result of such may be .. unclear.

乍一看似乎不一致,但这是一个定义明确的语法-但是技术细节被掩盖在一些相当普通的文档中;并且这些规则与其他类似C语法的语言中的规则有细微的区别.文档中缺少官方的EBNF并没有帮助.

As inconsistent as this may initially seem, it is a well-defined grammar - but the technical details are buried behind some fairly layman documentation; and the rules differ subtly from those in other C-syntax-like languages. The lack of an official EBNF in the documentation doesn't help.

尽管有解析细节,但从评估的角度来看,$a || $a = ..代码(有效且定义明确的语法)应保持定义良好,因为必须出现或"的左侧由于保证了短路,因此在权利之前.

Despite the parsing details, the $a || $a = .. code (which is valid and well-defined syntax) should remain well-defined from an evaluation viewpoint as the left side of the 'or' must occur prior to the right due to guaranteed short-circuiting.

为了对比,在JavaScript中,根据

For contrast, in JavaScript, a || a = 1 is parsed as (a || a) = 1 - which is also syntactically 'valid' code - per the ECMAScript Grammar Rules. However, a || a does not yield a valid Reference Specification Type and thus a runtime ReferenceError is thrown.

这篇关于JS vs PHP:与逻辑或运算符一起使用时,赋值运算符优先级的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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