因此我知道Javascript中的if
语句将其条件的结果转换为布尔值,然后执行它,如下所示
if(true) {
// run this
}
if(false) {
// do not run this
}
这很有效。但如果我这样做:
if('0' == false) {
// We get here, so '0' is a falsy value
}
然后我会期待这个
if('0') {
// We don't get here, because '0' is falsy value
}
但我得到了
if('0') {
// We *DO* get here, even though '0' is falsy value
}
那发生了什么事?显然,if
不会检查其条件是否为真值或假值,而是进行其他转换?
答案 0 :(得分:7)
这只是==
rules中那些相当复杂的“陷阱”之一。
比较x == y,其中x和y是值,产生true或false。这样的比较如下进行:
(4)如果Type(x)是Number而Type(y)是String, 返回比较结果x == ToNumber(y)。
(5)如果Type(x)是String而Type(y)是Number, 返回比较结果ToNumber(x)== y。
(6)如果Type(x)是布尔值,则返回比较结果ToNumber(x)== y。
(7)如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)。
在这种情况下,这意味着'0' == false
首先被强制执行'0' == 0
(通过规则#7),然后在第二次传递时,它被强制执行0 == 0
(按规则# 5)结果是真的。
由于false ~> 0
而不是'0' ~> true
(可能是预期的),这个特例非常棘手。但是,'0'
本身就是一个真值,并且行为可以用上述规则来解释。要在测试中使用严格的truthy-falsey相等(不同于严格相等)而不在相等期间进行隐式转换,请考虑:
!!'0' == !!false
(适用于所有值:!falsey -> true
和!truthy -> false
。)
答案 1 :(得分:3)
此:
if('0') {
// We *DO* get here, even though '0' is falsy value
}
检查字符串是空还是空,而不是它是否为零。任何非空字符串都是真实的。
执行此操作时:
if('0' == false) {
// We get here, so '0' is a falsy value
}
您要求JS引擎进行显式类型转换以尝试匹配两个操作数的类型。这不仅仅是询问一个操作数本身是否真实。
一般情况下,如果您几乎总是使用===
和!==
,并且只知道在所有情况下确实会发生什么,只会因为类型强制,您会发现意外结果会更少你完全理解非常复杂的强制规则,或者因为你知道会出现什么类型,并且你理解这些特定情况。
答案 2 :(得分:3)
if ('0' == false)
Javascript正在做一些名为type coercion
的事情。
遵循该链接中的规则,我们将遵循规则7:
如果Type(y)是布尔值,则返回比较结果x == ToNumber(y)
调用ToNumber(false)给我们一个数字0.结果现在开始有意义,但我们还没有完成,因为我们仍然有一个字符串和一个数字。这个过程再次开始,这次我们归结为规则5:
如果Type(x)是String而Type(y)是Number,则返回比较结果ToNumber(x)== y:“2”== 2
这次,左侧'0'被转换为数字:0。现在,我们最后可以比较两个数字,并且由于0等于0,结果为真。但是,重要的是要注意,这对于'0'
字符串的完整/虚假性质一无所知,因为它在被比较之前就被强制了。
if('0')
在这种情况下,没有比较;你只想知道单个值是“truish”还是“falsy”。没有使用类型强制,因为字符串可以根据其自身的优点被评估为truish或falsy。使用与以前相同的链接规则,我们可以找到以下信息:
在JavaScript中,不仅是JavaScript,我们还有所谓的虚假值。它们分别是:0,null,undefined,false,“”,NaN。请注意空字符串是空的,因为不同于php的例子,“0”将被认为是真实的
引用特别有用,因为它专门调用'0'字符串,但这不是必需的。足以知道空字符串是假的,并且任何其他字符串都是完整的,因为不评估字符串的内容并且不执行强制。 0
可能是一个假值,但是因为我们评估一个字符串而不是强制转换为一个数字,而'0'
具有某种值,所以它仍然是真实的。
答案 3 :(得分:1)
Javascript运算符==
进行类型转换,基本上没用。只是避免它。
例如:
[]
是truty但[] == false
true 1 == "1"
,[1] == "1"
,[[1]] == "1"
都是真的[1] == [[1]]
但是错误规则非常奇怪。例如,在第一种情况下,[]
转换为""
,转换为数字,值为0
。 false
也会转换为0
。所以最后他们比较平等。
但请注意,虽然从空字符串到数字的转换为0
,但parseInt("")
的结果为NaN
。
PS:真正有趣的是当你发现[30,20,10,3,2,1].sort()
返回[1,10,2,20,3,30]
时(是......数字,按字典顺序排列是)。不,我不是在开玩笑。