在JavaScript中,为什么"0"等于false,但是当使用'if'它本身不是假的吗?

下面的代码显示Javascript中的"0"为false:

>>> "0" == false
true


>>> false == "0"
true

那么为什么下面的语句打印"ha"呢?

>>> if ("0") console.log("ha")
ha
253618 次浏览

显示问题的表格:

 true if statement

< p > = =  javascript中所有对象类型的真实比较

故事寓意use === 严格相等显示正常

.

表生成credit: https://github.com/dorey/JavaScript-Equality-Table

0周围的引号使它成为一个字符串,它的值为true。

删除引号,它应该工作。

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

原因是,当显式执行"0" == false时,两边都被转换为数字,并且执行然后比较。

当你这样做:if ("0") console.log("ha"),字符串值正在测试。任何非空字符串都是true,而空字符串是false

< em >等于(= =)< / em >

如果两个操作数是不是同一类型的, JavaScript转换操作数,然后应用严格比较。如果任一操作数为数字或布尔值,则操作数将尽可能转换为数字;如果其中一个操作数是一个字符串,则另一个操作数将尽可能转换为字符串。如果两个操作数都是对象,则JavaScript比较当操作数引用内存中相同对象时相等的内部引用。

(来自Mozilla Developer Network中的比较运算符)

在PHP中,字符串"0"是假的(在布尔上下文中使用时是假的)。在JavaScript中,所有非空字符串都是真值。

诀窍在于,针对布尔值的==不会在布尔上下文中求值,它会转换为数字,对于字符串,则通过解析为十进制来完成。所以你得到的是Number 0而不是truthiness boolean true

这是一个非常糟糕的语言设计,这也是我们尽量不使用不幸的==操作符的原因之一。请改用===

这是按规格的。

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类型的值:

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

enter image description here

如果参数为空字符串(长度为零)则结果为假; 否则结果为true

现在,为了解释为什么"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求值,请使用===(也称为“严格”相等操作符)。

“if”表达式测试真实性,而双相等表达式测试与类型无关的等效性。正如这里的其他人指出的那样,字符串总是真实的。如果双等号测试它的两个操作数的真实性,然后比较结果,那么你会得到你直觉假设的结果,即("0" == true) === true。正如Doug Crockford在他出色的JavaScript:好的部分中所说,“[==强制操作数类型]的规则是复杂的,难以记忆的....传递性的缺乏令人担忧。”只要说其中一个操作数被类型强制与另一个操作数匹配,“0”最终被解释为数字0,当强制为布尔值时,它又等效于false(或当强制为数字时,false等效于0)就足够了。

这都是因为ECMA规格…由于此处指定的规则http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3…而if ('0')的值为true,因为这里指定了http://ecma262-5.com/ELS5_HTML.htm#Section_12.5

if (x)

使用JavaScript内部的toBoolean (http://es5.github.com/#x9.2)强制x

x == false

使用内部tonnumber强制(http://es5.github.com/#x9.3)或对象的toPrimitive强制(http://es5.github.com/#x9.1)

详细信息见http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/

// I usually do this:


x = "0" ;


if (!!+x) console.log('I am true');
else      console.log('I am false');


// Essentially converting string to integer and then boolean.

= =相等运算符在将参数转换为数字后计算参数。 因此字符串0" 0"被转换为数字数据类型,布尔值false被转换为数字0。 所以< / p >

"0" == false // true

同样适用于'

false == "0" //true

= = =严格的相等性检查用原始数据类型计算参数

"0" === false // false, because "0" is a string and false is boolean

同样适用于

false === "0" // false

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

字符串"0"不与任何参数进行比较,并且字符串在与任何参数进行比较之前都是真值。 它就像

if(true) console.log("ha");

if (0) console.log("ha"); // empty console line, because 0 is false

这是因为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)


我也有同样的问题,我找到了一个可行的解决方案如下:

原因是

    if (0) means false, if (-1, or any other number than 0) means true. following value are not truthy, null, undefined, 0, ""empty string, false, NaN

永远不要使用id之类的数字类型

      if (id) {}

对于可能值为0的id类型,我们不能使用if (id){},因为if(0)将意味着false,无效,这是我们想要的,它意味着有效为true id数。

所以对于id类型,我们必须使用以下方法:

   if ((Id !== undefined) && (Id !== null) && (Id !== "")){
                                                                                

} else {


}
                                                                            

对于其他字符串类型,我们可以使用if (string){},因为null, undefined,空字符串都将计算为false,这是正确的。

       if (string_type_variable) { }

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

当你使用“如果”时,它将是“错误的”。在以下情况下:

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

所以

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

这就是为什么你应该尽可能使用严格等式===或严格不等式!==的原因

"100" == 100

true,因为它只检查值,而不是数据类型

"100" === 100

false检查值和数据类型

我从搜索来到这里,寻找一个解决方案来评估"0"作为布尔值。 上面已经解释了技术细节,所以我不会深入讨论它,但我发现一个快速类型转换解决了它

因此,如果其他人像我一样,想要像PHP一样计算字符串10作为布尔值。然后你可以做上面的一些事情,或者你可以像这样使用parseInt():

x = "0";
if(parseInt(x))
//false