请考虑以下代码:
var y = 4;
alert( y>1 || (y++ ===4))
alert(y);
在这里,"y"警报 4。 但在下面的代码中:
var y = 4;
alert( y>1 && (y++ ===4))
alert(y);
在这里,"y"警报 5。 为什么 && 和 ||运算符显示两个不同的"Y"值?
在第一个示例中,您将缩短执行:
y>1 // This is already true
||
(y++ ===4) // So this is not executed
在 OR 条件语句中,如果第一个条件通过,则不检查后续条件,这是 y 的值递增的地方。
AND 条件反向工作。如果第一个条件为 false,则不会检查后续条件。
你没有问过,但可能也值得注意的是y++ === 4
将 y 的值与 4 进行比较后递增。因此,当执行下一条语句时,y 的值已增加到 5,即使与 4 进行比较时它是 4。如果您想将 y 的递增值与 4 进行比较,则先递增++y === 4
。这将递增,然后进行比较。
当逻辑表达式从左到右计算时,使用以下规则测试它们是否可能的"短路"计算:
假&&(任何东西)被短路评估为假。
真 ||(任何内容)的短路评估值为 true。
也就是说,对于|| (or)
运算符,如果第一个计算结果为 true,则不检查第二个条件,而在&&(and)
运算符的情况下,如果第一个计算结果为 false,则不检查第二个条件。
这里真正的答案是"因为跳过冗余处理会使程序运行得更快"。
编译器/解释器设计人员总是在寻找这样的小优化,这将使他们语言的程序运行得更快。
逻辑OR
(||
)会一直计算,直到它遇到第一个true
条件,或者直到它发现所有条件都false
。一旦OR
达到第一个true
条件,没有其他条件可以改变OR
最终将计算为true
的事实,那么为什么要费心执行它们呢?
出于同样的原因,逻辑AND
(&&
)会计算直到它遇到第一个false
条件(或发现所有条件都true
)。
总是在布尔逻辑序列中执行所有条件的语言非常罕见;你应该期望AND
和OR
在你学习的下一门语言中以这种方式行事。
在您的示例中,这意味着解释器发现OR
测试中的y>1
为真,因此它立即跳过了其余条件,包括后递增 (++
)。 执行了第一个和第二个AND
条件(因为第一个条件是true
的,而AND
只在false
上停止)。
请注意,如果从y = 1
开始,则OR
将递增y
,但您的AND
不会。
你应该对你的OR
条件进行排序,以便它能最快找到true
,你的AND
条件应该被排序为最快找到false
,其中"最快"意味着任何逻辑路径让你以最少的处理得到答案。