JavaScript的if语句的语义是什么?

5

我一直认为 if 语句会像 == true 一样比较其参数。然而,在 Firebug 中进行的下面实验证实了我最担心的事情——经过 15 年的 JavaScript 编程,我仍然不知道它到底是怎么回事:

>>> " " == true
false
>>> if(" ") console.log("wtf")
wtf

我的世界观在这里崩溃了。我可以运行一些实验来了解更多,但即使如此,我仍然会因为浏览器的怪癖而失眠。这是否在某个规范中?它在各种浏览器之间是否一致?我会掌握 JavaScript 吗?


很奇怪,我很好奇看到答案。 - theraccoonbear
5个回答

7
"If the two operands are not of the same type, JavaScript will convert them and then perform a strict comparison. If one operand is a number or boolean, both operands will be converted to numbers. If one operand is a string, the other operand will be converted to a string as well."
Reference: https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Operators/Comparison_Operators "So the first one does:"
Number(" ")==Number(true)

第二个表达式的求值方式如下:
if(Boolean(" ")==true) console.log("wtf")

这是最明智的解释。if语句转换为布尔值。如果有人能找到此行为的规范,就可以获得额外的奖励分数。 - gtd
1
关于发生在if语句中的转换,Mozilla文档有以下说明:"任何不是undefined、null、0、NaN或空字符串("")的值以及任何对象,包括一个布尔对象其值为false,都会在传递给条件语句时被视为true。" - kloffy
关于使用Boolean(value)进行转换的内容:“如果省略值或为0,-0,null,false,NaN,undefined或空字符串(“”),则对象的初始值为false。” - kloffy
2
我一个JS忍者朋友刚刚给我发了这个规范链接:http://bclary.com/2004/11/07/#a-11.9.3 - Bart

3
我猜问题出在第一部分,而不是第二部分。
它可能进行了一些奇怪的强制转换(最有可能的是将true强制转换为字符串,而不是将" "强制转换为布尔值)。
FireBug对于Boolean(" ")返回什么?

编程语言中的真实性定义已经引发了许多圣战,但在JavaScript中,我认为既然“==”进行类型转换,“===”则是精确匹配,那么“== true”就是真实性的自然定义。 - gtd
Boolean(" ") => true Boolean("") => false - gtd
所以,答案可能是“==”运算符进行了向后转换(true => string "true"),然后比较失败了。但是如果我找不到任何指定“==”的转换规则的参考资料,请杀了我。 - DVK
请查看下面的两个答案 :) - gtd

3

JavaScript在这方面有些古怪。请注意,JavaScript有=====两种比较方式。我本以为

" " == true

应该是true,但是。
" " === true

如果变量类型不同,使用===运算符将返回false。该运算符不进行转换,它检查运算符两侧的值和类型是否相同。而==会将“真”值转换为true,“假”值转换为false。
这可能是答案,来自于Mozilla文档中的JavaScript Comparison Operators等于(==) 如果两个操作数的类型不同,JavaScript会将操作数转换后再进行严格比较。如果任一操作数是数字或布尔值,则将操作数转换为数字;如果任一操作数是字符串,则将另一个操作数转换为字符串。
强烈推荐阅读:Douglas Crockford on JavaScript

好的链接,我有《JavaScript语言精粹》这本书,但我不知道它去哪了。 - gtd

2

答案:aTruthyValue和true并不相同。

if语句的语义很简单:

if(aTruthyValue) {
  doThis
} else {
  doThat
}

现在只是定义什么是真值。不幸的是,真值并不仅仅是 "== true" 或 "=== true"。ECMA-262 1.5第9.2节解释了哪些值是真值,哪些不是。请参阅ECMA-262 1.5

1
+1 对于最直接的答案,并附上实际规范的链接! - Daniel Pryden

0

我建议尽可能使用 ===,即使只是为了避免存在危机。


这纯粹是愚蠢的。String.prototype.f = function () { return this }; "foo".f() === "foo" // 结果是什么?身份就是身份。这是一个特殊情况,不是正常情况。 - user166390

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