【问题标题】:Do the && and || operators convert their operands to booleans?做 && 和 ||运算符将其操作数转换为布尔值?
【发布时间】:2011-11-27 22:53:34
【问题描述】:

Flanagan 的 O'Reilly JavaScript 书指出:

与 && 和 || 不同运营商,!运算符将其操作数转换为 一个布尔值 [...] 在反转转换后的值之前。

如果这些逻辑运算符不将操作数转换为布尔值,如何计算表达式?

【问题讨论】:

标签: javascript


【解决方案1】:

他们确实将值转换为布尔值,但确定如何继续评估表达式。表达式的 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
  • 哈哈是的,没错。我目前正在(非正式地)向一群 13 岁的孩子教授它,我不得不想知道当他们有一天看到其他无聊的语言时会怎么想:-)
  • 感谢您详细说明返回值
【解决方案2】:

根据specification,第 11.11 节:二元逻辑运算符:

产生式 [of 评估 &&] ... 评估如下:

  1. 令 lref 为评估 LogicalANDExpression 的结果。
  2. 设 lval 为 GetValue(lref)。
  3. 如果ToBoolean(lval) 为假,则返回lval。
  4. 设 rref 为计算 BitwiseORExpression 的结果。
  5. 返回 GetValue(rref)。

产生式 [of 评估 ||] ... 评估如下:

  1. 设 lref 为计算逻辑或表达式的结果。
  2. 设 lval 为 GetValue(lref)。
  3. 如果ToBoolean(lval) 为真,则返回lval。
  4. 设 rref 为评估 LogicalANDExpression 的结果。
  5. 返回 GetValue(rref)。

所以内部这个值被“转换为布尔值”。然而,由于这从未公开——并且整个语义解释是一个可以/被“优化”的抽象——&&|| 的行为可以通过使用真假值来简单地解释(ToBoolean 涵盖:真值是ToBoolean 返回真值的值,所有其他值都是假的)。

&& 的逻辑表是:

a b 结果
真实的任何 b
假任何一个

||的逻辑表是:

a b 结果
真实的任何一个
假任何 b

请注意,返回的是 ab 的评估结果。

编码愉快。


为了完整起见,从第 9.2 节开始:

抽象操作ToBoolean 将其参数转换为布尔类型的值 ...

  • 未定义 - 错误
  • 空 - 假
  • boolean(不是 Boolean 对象!) - 结果等于输入参数(无转换)。
  • number(不是 Number 对象!) - 如果参数为 +0、-0 或 NaN,则结果为 false;否则结果为真。
  • string (not String object!) - 如果参数是空字符串(它的长度为零),则结果为假;否则结果为真。
  • 对象 - 真

【讨论】:

  • 谢谢!说 JavaScript 表达式是假的和说它是假的有区别吗?
  • @ppecher:“falsey”表示一个“行为类似于”false 的值,此时需要一个布尔值。换句话说,任何ToBoolean 将转换为false 的东西。所以,""0null等都是“假的”。 “false”表示实际的布尔值,false
  • @ppecher:当你说“false”时,大多数人会认为它一个布尔值(值为false)。当您说“falsy”时,大多数人会理解它是一个值,如果转换为布尔值,则为 false,但不一定是布尔值本身。
【解决方案3】:

操作数被解释为布尔值以评估表达式,但 && 或 || 的返回值始终是操作数之一。

例如:

true && 0 === 0, not false
1 || false === 1, not true

【讨论】:

  • 由于我们有不同的答案,有没有人有文件可以指点我们?
【解决方案4】:

因为 JavaScript 有一个 truthiness 的概念,它涵盖的不仅仅是布尔值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-07
    • 2019-07-24
    相关资源
    最近更新 更多