JavaScript中的所有假值

266
JavaScript中哪些值是“假值”,也就是在if(value)value ?!value表达式中被评估为false的值是什么?

Stack Overflow上已经讨论了一些关于假值目的的话题,但没有详尽完整的答案列出所有的假值是什么。

我在MDN JavaScript参考文档中找不到任何完整的列表。当寻找JavaScript中假值的完整权威列表时,令人惊讶的是,排名靠前的结果是博客文章,其中一些明显有遗漏(例如NaN),而且没有像Stack Overflow那样的格式,可以添加评论或其他答案来指出奇怪的问题、遗漏、错误或注意事项。所以,制作一个完整的列表似乎是有意义的。


2
你有查看语言规范吗?(http://www.ecma-international.org/ecma-262/5.1/) - Pointy
1
@tibos http://blog.stackoverflow.com/2011/07/its-ok-to-ask-and-answer-your-own-questions/请放心提问并自行回答的做法是可以接受的。 - user56reinstatemonica8
5
https://dorey.github.io/JavaScript-Equality-Table/ 是一个很棒的资源,其中有一个用于真值判断的 if() 选项卡。 - cloudfeet
4
哇,真的很有用,谢谢! [[]] == "" 但是 [] != []?我的脑袋痛了… - user56reinstatemonica8
1
ECMA 262规范详细说明了这些比较规则,具体内容为第11.9.1至11.9.6章节:http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.3如果你能更新你的回答并包含这个参考链接,那就太好了,因为它提供了如何确定真/假的规则。 - Shaun Wilson
显示剩余2条评论
4个回答

448
JavaScript中的假值
  • false
  • Number类型的零: 0,还包括-00.0和十六进制形式的0x0感谢RBT
  • BigInt类型的零:0n0x0n(2020年新增,感谢GetMeARemoteJob
  • ""''`` - 长度为0的字符串
  • null
  • undefined
  • NaN
  • document.all(仅在HTML浏览器中)

"Falsey"的意思是JavaScript内部的ToBoolean函数返回false ToBoolean!valuevalue ? ... : ...;if (value)的基础。这里是它的官方规范(2020年工作草案)(自1997年的第一个ECMAscript规范以来唯一的变化是添加了ES6的Symbols,它们始终为真值,并且上面提到了BigInt

参数类型 | 结果 ---|--- 未定义(Undefined) | 返回 false。 空值(Null) | 返回 false。 布尔值(Boolean) | 返回参数值。 数字(Number) | 如果参数为 +0-0NaN,返回 false;否则返回 true。 字符串(String) | 如果参数为空字符串(长度为零),返回 false;否则返回 true。 大整数(BigInt) | 如果参数为 0n,返回 false;否则返回 true。 符号(Symbol) | 返回 true。 对象(Object) | 返回 true

使用==进行比较(宽松相等性)

值得讨论的是,虚假值与==的宽松比较,它使用ToNumber()可能会由于底层差异而引起一些困惑。它们有效地分为三组:

  • false, 0, -0, "", '' 都可以使用 == 进行比较
    • 例如: false == "", '' == 0,因此 4/2 - 2 == 'some string'.slice(11);
  • null, undefined 可以使用 == 进行比较
    • 例如: null == undefined,但是 undefined != false
    • 值得一提的是,虽然 typeof null 返回 'object',但是 null 不是对象,这是一个长期存在的错误/怪癖,为了保持兼容性而没有修复。它不是真正的对象,而对象都是真值(除了那个“故意违反规定”的 document.all 在实现 HTML 的 Javascript 中)
  • NaN 无法与任何东西进行匹配,包括 =====,甚至是它自己
    • 例如: NaN != NaNNaN !== NaNNaN != falseNaN != null
使用“严格相等”(===)时,不会出现这样的分组。只有false === false
这就是为什么许多开发人员和许多风格指南(例如standardjs)更喜欢使用===,并且几乎从不使用==的原因之一。

值为Truthy的实际== false

"Truthy"简单地意味着JavaScript内部的ToBoolean函数返回true。要注意的是JavaScript的一个怪癖(也是另一个选择===而非==的好理由):有可能一个值是truthy的(ToBoolean返回true),但同时也等于false

你可能认为if (value && value == false) alert('Huh?')是一种逻辑上不可能发生的情况,但实际上会发生,比如:

  • "0"'0' - 它们是非空字符串,是真值,但是 JavaScript 的 == 会将数字与等价的字符串匹配(例如,42 == "42")。由于 0 == false,如果 "0" == 0,则 "0" == false
  • new Number(0)new Boolean(false) - 它们是对象,是真值,但是 == 看到它们的值,这些值等于 false
  • 0 .toExponential(); - 一个具有等价于 0 的数值的对象
  • 任何类似的构造,它们包装了一个假相等的值,但类型为真值
  • [][[]][0](感谢 cloudfeet 提供 JavaScript Equality Table link

更多的真值

以下是一些人们可能认为是假值但实际上是真值的值。

  • -1和所有非零负数

  • ' '" ""false"'null'…所有非空字符串,包括只有空格的字符串

  • typeof返回的任何内容,它总是返回一个非空字符串,例如:

  • 除了浏览器中的"故意违规"document.all之外的任何对象。请记住,尽管typeof表明null是一个对象,但实际上它并不是一个对象。例如:

    • {}
    • []
    • function(){}() => {} (任何函数,包括空函数)
    • ErrorError 的任何实例
    • 任何正则表达式
    • 使用new创建的任何内容(包括new Number(0)new Boolean(false)
  • 任何Symbol

true1"1"[1]== 比较时,会返回 true


3
了解一下,!if?..: 具有共同点,即它们对值调用内部的 ToBoolean 函数。这些值在 !if 等上下文中的行为已经由它们的名称暗示了:它们是“假值”。我有点担心其他人会看到答案并认为:“哦,所以在这种情况下(!if?...:),值是 false,但用 !! 却是 true。”,但他们不理解其中的概念。另外两个要点:1)v ? true : false 只是 !!v 的冗长写法。2)typeof 始终返回一个非空字符串,即真值。 - Felix Kling
1
即使具体查看typeof nulltypeof undefined也没有意义。你可以简单地说非空字符串是真值。 - Felix Kling
1
我明白了,但这与原问题无关 ;) 添加太多有些相关但不相关的信息可能会让读者感到困惑。 - Felix Kling
5
我刚刚了解到document.all是假值 - Claudiu
3
关于宽松比较:由于布尔值会被转换为数字,所以x == false会调用ToNumber(x),这与ToBoolean(x)非常不同。也许值得解释一下。另外我刚注意到我很久以前已经评论过这个答案 :D - Felix Kling
显示剩余6条评论

4

补充一下 @user568458 提到的假值列表:

  • In addition to integer number 0, the decimal number 0.0, 0.00 or any such zeroish number is also a falsy value.

    var myNum = 0.0;
    if(myNum){
        console.log('I am a truthy value');
    }
    else {
        console.log('I am a falsy value');
    }
    

    Above code snippet prints I am a falsy value

  • Similarly hex representation of the number 0 is also a falsy value as shown in below code snippet:

    var myNum = 0x0; //hex representation of 0
    if(myNum){
        console.log('I am a truthy value');
    }   
    else {
        console.log('I am a falsy value');
    }
    

    Above code snippet again prints I am a falsy value.


8
JavaScript дёҚж”ҜжҢҒж•ҙж•°зұ»еһӢгҖӮ0гҖҒ0x0гҖҒ0.0 е’Ң 0.00 еҸӘжҳҜиЎЁзӨәзӣёеҗҢ IEEE-754 64 дҪҚжө®зӮ№ж•°йӣ¶зҡ„дёҚеҗҢеӯ—йқўйҮҸгҖӮ - fredoverflow

4

不要忘记非空字符串"false"也会被评估为true


10
因此它不是 falsy 值,这就是所要求的吗? - Bergi
6
得分了。这是一个你可能期望为假却不是假的值,值得注意,我认为它值得在全面列表中提到。 - MrMcPlad
4
已添加到列表中...但是我们不要试图把它变成所有可能的真值的全面列表!那样会花费一些时间 :-) - user56reinstatemonica8

2
作为主题的补充,从ES2020开始,我们有一个新值是虚假的,它是BigInt零(0n):
0n == false // true
-0n == false // true
0n === false // false
-0n === false // false

因此,现在我们总共有7个“假”值(不包括用户上面提到的document.all,因为它是DOM的一部分而不是JS)。

1
不错!谢谢,我还没有听说过这个,我已经将它添加到大列表中,并附上了链接,以表彰你提出的答案。 - user56reinstatemonica8

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