【发布时间】:2011-11-27 22:53:34
【问题描述】:
Flanagan 的 O'Reilly JavaScript 书指出:
与 && 和 || 不同运营商,!运算符将其操作数转换为 一个布尔值 [...] 在反转转换后的值之前。
如果这些逻辑运算符不将操作数转换为布尔值,如何计算表达式?
【问题讨论】:
标签: javascript
Flanagan 的 O'Reilly JavaScript 书指出:
与 && 和 || 不同运营商,!运算符将其操作数转换为 一个布尔值 [...] 在反转转换后的值之前。
如果这些逻辑运算符不将操作数转换为布尔值,如何计算表达式?
【问题讨论】:
标签: javascript
他们确实将值转换为布尔值,但仅确定如何继续评估表达式。表达式的 result 不一定是布尔值(事实上,如果你的操作数都不是布尔值,那么它不会给你一个布尔值):
var x = false || 'Hello' // gives you 'Hello'
var y = 0 && 1 // gives you 0, because 0 is "falsy" and short circuits
var z = 1 || 2 // gives you 1, because 1 is "truthy" and short circuits
【讨论】:
ToBoolean(在 ECMAScript ed. 5 的第 11.11 节下)......没有票了,但这是正确的。
true && 0放到JS控制台,输出会是0,但是如果你把if(true && 0) { true; } else { false; },输出会是false。
根据specification,第 11.11 节:二元逻辑运算符:
产生式 [of 评估 &&] ... 评估如下:
ToBoolean(lval) 为假,则返回lval。 产生式 [of 评估 ||] ... 评估如下:
ToBoolean(lval) 为真,则返回lval。 所以内部这个值被“转换为布尔值”。然而,由于这从未公开——并且整个语义解释是一个可以/被“优化”的抽象——&& 和|| 的行为可以通过使用真假值来简单地解释(ToBoolean 涵盖:真值是ToBoolean 返回真值的值,所有其他值都是假的)。
&& 的逻辑表是:
a b 结果 真实的任何 b 假任何一个
||的逻辑表是:
a b 结果 真实的任何一个 假任何 b
请注意,返回的是 a 或 b 的评估结果。
编码愉快。
为了完整起见,从第 9.2 节开始:
抽象操作ToBoolean 将其参数转换为布尔类型的值 ...
【讨论】:
false 的值,此时需要一个布尔值。换句话说,任何ToBoolean 将转换为false 的东西。所以,""、0、null等都是“假的”。 “false”表示实际的布尔值,false。
操作数被解释为布尔值以评估表达式,但 && 或 || 的返回值始终是操作数之一。
例如:
true && 0 === 0, not false
1 || false === 1, not true
【讨论】:
因为 JavaScript 有一个 truthiness 的概念,它涵盖的不仅仅是布尔值。
【讨论】: