在JavaScript中,为什么“0”等于false,但是当'if'测试时它本身并不是假的?

时间:2011-09-30 19:34:41

标签: javascript boolean

以下显示Javascript中的"0"为false:

>>> "0" == false
true

>>> false == "0"
true

那么为什么以下打印"ha"

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

14 个答案:

答案 0 :(得分:323)

显示问题的表格:

truthy if statement

和== truthy comparisons of all object types in javascript

故事的道德使用=== strict equality displaying sanity

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

答案 1 :(得分:238)

原因是当你明确地执行"0" == false时,双方都被转换为数字,然后然后执行比较。

执行:if ("0") console.log("ha")时,正在测试字符串值。任何非空字符串都是true,而空字符串是false

  

等于(==)

     

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

     

(来自Mozilla开发者网络中的Comparison Operators

答案 2 :(得分:36)

这是根据规范。

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

  

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

现在,解释为什么"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方法并最终看起来是假的。

如果要使用==使用GetValue操作评估事物,如果要使用ToBoolean进行评估,请使用===(也称为“严格”等于运算符)

答案 3 :(得分:12)

这是PHP,其中字符串"0"是假的(false-when-used-in-boolean-context)。在JavaScript中,所有非空字符串都是真实的。

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

这是一个非常糟糕的语言设计,这是我们尝试不使用不幸的==运算符的原因之一。请改用===

答案 4 :(得分:7)

// 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.

答案 5 :(得分:4)

0周围的引号使其成为一个字符串,评估为true。

删除引号,它应该有用。

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

答案 6 :(得分:1)

“if”表达式测试真实性,而对于类型无关等效性的双重测试。正如其他人在此指出的那样,字符串总是很简洁。如果双重等于测试其两个操作数的真实性然后比较结果,那么你将得到你直观假设的结果,即("0" == true) === true。正如Doug Crockford在他出色的 JavaScript:Good Parts 中所说的那样,“= =强制其操作数类型的规则”是复杂和不可取的......缺乏传递性是令人震惊的。 “可以说其中一个操作数被强制类型化以匹配另一个操作数,并且“0”最终被解释为数字零,当强制转换为布尔值时,它又等于false(或者false等于零)当强迫一个数字时。)

答案 7 :(得分:1)

这完全是因为ECMA规范... "0" == false因为此处指定的规则http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.3 ...而if ('0')因为此处指定的规则而{{1}}评估为真{{1}} 3}}

答案 8 :(得分:1)

== 相等运算符将参数转换为数字后对其求值。 因此,将字符串零“ 0”转换为Number数据类型,将布尔值false转换为Number 0。 所以

  

"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

`

答案 9 :(得分:0)

if (x) 

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

x == false

使用内部toNumber强制(http://es5.github.com/#x9.3)或对象的原始强制(http://es5.github.com/#x9.1)强制双方

有关详细信息,请参阅http://javascriptweblog.wordpress.com/2011/02/07/truth-equality-and-javascript/

答案 10 :(得分:0)

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

if ("0") 

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

Javascript中还有其他真实值,它们在布尔上下文中会被强制为true,因此执行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)

答案 11 :(得分:0)

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

原因是

    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) {}

对于ID类型(可能值为0),我们不能使用if(id){},因为if(0)表示假,无效,我们希望它表示有效的真实ID号。

因此对于id类型,我们必须使用以下内容:

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

                                                                            }
                                                                            

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

       if (string_type_variable) { }

答案 12 :(得分:0)

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

使用“ if”时,在以下情况下为“ false”:

[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)

答案 13 :(得分:0)

这就是为什么您应该尽可能使用严​​格相等===或严格不平等!==

的原因

"100" == 100

true,因为这仅检查值,而不检查数据类型

"100" === 100

false会检查值和数据类型