[]== ![] 答案为什么会是True?

开发 前端
在这段算法里,和「[] == ![]」匹配的是条件 7,所以会递归地调用「[] == ToNumber(false)」进行比较。在 9.3 节中定义了 ToNumber 原语,ToNumber(false) 等于 0,于是比较变为「[] == 0」。在此处因为 [] 是对象,比较过程走分支 9,依「ToPrimitive([]) == 0」比较。

解析1

  • [] == !true // ! 操作符的优先级高于==,所以先执行!操作;“!”是取反操作,空数组是对象,对象为真,取反之后就为false了
  • [] == false // !true 得到的是 false
  • [] == 0 // 比较规则1:如果值为true或false,则转成1或0来继续比较
  • [] == 0 // 执行左侧的 [] 的 valueOf 方法,而 [] 是对象,所以 [].valueOf() 返回本身 []
  • "" == 0 // 执行左侧的 [] 的 toString 方法,[].toString() 返回 ""
  • 0 == 0 // 比较规则2:如果一个值是数字,一个值是字符串,则把字符串转换为数字,再进行比较,"" 转成数字是 0。
  • 最终是执行 0 == 0 ,结果为 true 。

解析2

首先,“!”是取反操作,空数组是对象,对象为真,取反之后就为false了。

然后,相等运算符的比较有指定的规则,具体请参阅诸如《JavaScript权威指南》或者《JavaScript高级程序设计》等书目。其中有两条指出:

  1. 如果其中一个值是true,则将其转换为1再进行比较。如果其中一个值是false,则将其转换为0再进行比较。
  2. 如果一个值是对象,另一个值是数字或字符串,则将对象转换为原始值再进行比较。对象通过toString()方法或valueOf()方法转换为原始值。JavaScript语言核心的内置类首先尝试使用valueOf(),在尝试使用toString(),除了日期类,日期类只使用toString()方法,那些不是JavaScript语言核心中的对象则通过各自实现中定义的方法转换为原始值。

有了以上两条作为基础,我们再来看问题。

控制台指出等号右边为布尔值,由第一条可知,它将转换为数字0,也就是数字类型。

现在变成了空数组和数字 0 的比较。由第二条可知,空数组会首先调用valueOf()方法,但是这里需要注意的是:数组、函数和正则表达式调用valueOf()方法后,只返回对象本身。

所以,继续调用toString()方法,空数组调用toString()后,众所周知会返回 0 ;于是两边相同。也就是为什么有了后面所示结果的原因了。"" == ![] //true1 == ![] // false0 == ![] // true可以一句话概括:任意值与布尔值之间的比较都是数字0和1之间的比较。

"" == ![] //true

1 == ![] // false

0 == ![] // true

可以一句话概括:任意值与布尔值之间的比较都是数字0和1之间的比较。

规范

首先,== 的定义是:

GetValue 会获取一个子表达式的值(消除掉左值引用),在表达式 [] == ![] 中,[] 的结果就是一个空数组的引用,而 ![] 就有意思了,它会按照 11.4.9 和 9.2 节的要求得到 false。

在这段算法里,和「[] == ![]」匹配的是条件 7,所以会递归地调用「[] == ToNumber(false)」进行比较。在 9.3 节中定义了 ToNumber 原语,ToNumber(false) 等于 0,于是比较变为「[] == 0」。在此处因为 [] 是对象,比较过程走分支 9,依「ToPrimitive([]) == 0」比较。ToPrimitive 默认是调用 toString 方法的(依 8.2.8),于是 ToPrimitice([]) 等于空字符串。结果,[] == ![] 的比较最后落到了 ''==false 上,按照 11.9.3 中的定义会依分支 5 比较 「ToNumber('')==0」,ToNumber('') 依 9.3.1 等于 0,所以结果为 true。

文章出自:前端餐厅,如有转载本文请联系前端餐厅今日头条号。

github:​​https://github.com/zuopf769​

责任编辑:武晓燕 来源: 今日头条
相关推荐

2024-09-11 08:38:02

JavaScriptC#语言编程

2012-06-11 09:07:39

Windows 8微软

2011-06-20 08:43:15

Windows 8开发人员

2023-04-26 07:06:56

CPU主板半导体器件

2022-12-22 14:32:37

JavaScript编程语言

2021-06-24 15:22:10

Spring云原生平台

2020-01-14 11:23:16

SSDOP磁盘

2019-12-11 14:23:50

大数据商业 价值分析

2015-11-23 10:09:30

Java

2018-05-08 06:51:02

2024-03-20 09:00:00

人工智能AI大模型深度学习

2015-11-23 11:33:37

2023-09-19 08:03:01

JavaScriptevery()

2020-07-01 14:11:37

数据行业设计

2016-10-24 11:35:12

2021-07-21 22:11:20

比特币加密货币货币

2016-10-24 18:49:01

2021-07-26 09:16:34

智能家居安全物联网

2016-01-04 08:52:11

2022-03-15 16:19:13

物联网物联网 2.0IoT
点赞
收藏

51CTO技术栈公众号