Javascript的细节(三): 抽象相等,严格相等和其他

发表于更新于阅读时长 3 分钟

在ES2015中一共提供了四种相等,下文将一一介绍

1

1. 严格等于(===)

除了===之外,还用在Array.prototype.indexOf,Array.prototype.lastIndexOfswitch ... case语句中

显然的,在使用严格等于时,先比较两个值的类型,如果不同则不相等

如果两值的类型不为Number,则只有他们的值相等时才相等

若它们的类型为Number时, 则有两个特例

  1. NaN与任何值都不等
  2. +0与-0相等

当然还会遇到浮点数精度问题

总而言之用这个!

2.抽象相等(==)

也可以叫宽松相等,会把两个值转换成可以比较的类型之后再比较

转换的规则非常复杂,但是可以抽象成如下规则:

  1. Javacript 中的值可以分为两种,原始值(包括undefined,null,Number,String,Boolean和ES6新增的Symbol)和Object
  2. undefinednull只互相相等,和其他任何类型的值都不等
  3. Symbol和任何类型的值都不等
  4. 除了1,2中提及的类型,剩下三种原始的类型互相比较都会被转换成Number类型再进行比较
  5. 而一个Object被用来和原始值进行比较时,会被转换成原始值,步骤如下
    1. 先尝试调用该Object的 toString 方法
    2. 如果1不存在,再尝试调用该Object的 valueOf 方法
    3. 如果都不存在或者得到的值不是原始值则抛错
    4. 最后将得到的值进行宽松相等(==)比较
  6. 两个Object互相比较时,只有为对同一个Object的引用时才相等

一个小例外是document.all,出于历史原因,虽然在现代浏览器中访问它的值是一个HTMLCollection,但是它和undefined/null宽松相等

是大部分 JavaScript 笑话的来源

3.同值相等

同值相等只有在两个值在任何环境下都可以发挥出同样的功能,即满足里氏替换原则

Object.is使用了这个机制,在对Object的{ writable: false }写入判断是否会抛错的也是这个机制

它和严格相等的主要区别在于

  1. +0和-0不相等
  2. NaNNaN相等

4.同值零相等

和上一个类似,除了+0和-0在该机制中相等.或者说和严格相等类似,除了NaNNaN在该机制中相等

ES6中引入的MapSet中使用该机制判断来是否是同一个key


  1. 主要参考该文
© 2016 - 2022Austaras Devas