如下所示,Javascript中的"0"为false:

>>> "0" == false
true

>>> false == "0"
true

那么下面为什么打印“哈”呢?

>>> if ("0") console.log("ha")
ha

当前回答

这都是因为ECMA规格…"0" == false,因为这里指定的规则http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3…if('0')的结果为true,因为这里指定的规则http://ecma262-5.com/ELS5_HTML.htm#Section_12.5

其他回答

这都是因为ECMA规格…"0" == false,因为这里指定的规则http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3…if('0')的结果为true,因为这里指定的规则http://ecma262-5.com/ELS5_HTML.htm#Section_12.5

在JS中,“==”符号不检查变量的类型。因此,“0”= 0 = false(在JS中为0 = false),在这种情况下将返回true,但如果使用“===”,结果将为false。

当你使用"if"时,在以下情况下它将是"false":

[0, false, '', null, undefined, NaN] // null = undefined, 0 = false

So

if("0") = if( ("0" !== 0) && ("0" !== false) && ("0" !== "") && ("0" !== null) && ("0" !== undefined) && ("0" !== NaN) )
        = if(true && true && true && true && true && true)
        = if(true)

The "if" expression tests for truthiness, while the double-equal tests for type-independent equivalency. A string is always truthy, as others here have pointed out. If the double-equal were testing both of its operands for truthiness and then comparing the results, then you'd get the outcome you were intuitively assuming, i.e. ("0" == true) === true. As Doug Crockford says in his excellent JavaScript: the Good Parts, "the rules by which [== coerces the types of its operands] are complicated and unmemorable.... The lack of transitivity is alarming." It suffices to say that one of the operands is type-coerced to match the other, and that "0" ends up being interpreted as a numeric zero, which is in turn equivalent to false when coerced to boolean (or false is equivalent to zero when coerced to a number).

这是因为JavaScript在布尔上下文和代码中使用类型强制

if ("0") 

将在布尔上下文中被强制为true。

在Javascript中还有其他的真值,在布尔上下文中会被强制为真,因此执行if块:-

if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)

这是按规格的。

12.5 The if Statement 
.....

2. If ToBoolean(GetValue(exprRef)) is true, then 
a. Return the result of evaluating the first Statement. 
3. Else, 
....

根据规范,ToBoolean是

抽象操作ToBoolean根据表11将其参数转换为Boolean类型的值:

这个表格是这样描述字符串的:

如果参数为空String(其长度为零),则结果为假; 否则结果为真

现在,为了解释为什么"0" == false,您应该读取相等运算符,它表示它从抽象操作GetValue(lref)中获得其值,与右侧的相同。

将相关部分描述为:

if IsPropertyReference(V), then 
a. If HasPrimitiveBase(V) is false, then let get be the [[Get]] internal method of base, otherwise let get
be the special [[Get]] internal method defined below. 
b. Return the result of calling the get internal method using base as its this value, and passing 
GetReferencedName(V) for the argument

或者换句话说,字符串有一个基元,它会回调内部的get方法,结果看起来是false。

如果你想用GetValue运算来求值,请使用==,如果你想用ToBoolean运算,请使用===(也称为“严格”相等运算符)