深入探讨 ![] == [] 的值

48 阅读3分钟

一、![] == []的值

感叹号(!)用于取反变量的真假值。而等号(==)则是用来比较两个值是否相等的运算符,先将两个数值转为相同类型再进行比较。分以下四步进行:

1.根据运算符优先级, !的优先级是大于==的,所以先会执行![]

!用于取反变量的真价值,false、0、null、undefined、NaN以及空字符串('')取反都为true,其余都为false。

所以  ![]实际上返回了 false

也就是说 ![] == [] 相当于

false == []

2.JavaScript 中的类型转换规则 如果有一个操作数是布尔值,在比较相等性之前先将其转换为数值,即调用Number()函数。

Number(false)为0

也就是说 false == [] 相当于 

0 == []

3.如果一个是引用数据类型,另一个是数值或字符串,把引用数据类型转换成基本数据类型再比较。引用数据类型转换成基本数据类型,利用它的toString或者valueOf方法。

  1. 首先,JavaScript会尝试调用引用数据类型的valueOf()方法。
  2. 如果valueOf()方法返回的是一个基本数据类型,则此值将被使用。
  3. 如果valueOf()方法返回的不是基本数据类型,则JavaScript会尝试调用对象的toString()方法。
  4. 如果toString()方法返回一个基本数据类型,则此值将被使用。
  5. 如果toString()方法返回的是引用数据类型本身,则会调用Number()包装器函数,返回NaN。

而对于空数组,[].valueOf()不能将其转为基本数据类型

所以调用toString()

[].toString() -> '' (返回空字符串)

也就是说  0 == [] 相当于

0 == ''

4.如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值

Number('')  返回的是 0

也就是说0 == ''相当于

0 == 0 

故结果为true

总结

  1. ![] == []
  2. flase == []
  3. 0 == []
  4. 0 == ''
  5. 0 == 0
  6. true  

二、有关==!==的规则

1、如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值,即调用Number()函数。

2、如果有一个操作数是字符串,另一个值是数值,在比较相等性之前先将字符串转换为数值;即调用Number()函数。

3、如果有一个操作数是引用数据类型,另一个是数值或字符串,把引用数据类型转换成基础类型的值再比较。引用数据类型转换成基本数据类型,利用它的toString()或者valueOf()方法。

4.null 和undefined 是相等的

5.要比较相等性之前,不能将null 和 undefined 转换成其他任何值

6.如果有一个操作数是NaN,则相等操作符直接返回 false ,不相等操作符返回 true。即使两个操作数都是NaN,相等操作符也返回 false了;因为按照规则, NaN 不等于 NaN

7.如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数都指向同一个对象,则相等操作符返回 true;否则, 返回false

8.[] 和 {} 都是属于引用类型,引用类型是存放在栈内存中的,而在堆内存中会有一个或者多个地址来指向这个栈内存相对应的数据。所以在使用 == 操作符的时候,对于引用类型的数据,比较的是地址,而不是真实的值。

三、练习 !{} == {}

  1. !{} == {}
  2. false == {}
  3. 0 == {}
    {}.toString()返回的是NaN
  4. 0 == NaN
    如果有一个操作数是NaN,则相等操作符直接返回 false
  5. false