JavaScript 中存在各种比较,例如常见的 ==(loosely equal) ===(strictly equal) Object.is isNaN Number.isNaN 等等,
这些操作符或者函数都可以用来比较/判断。本文继续根据 ECMA规范 来学习和比较他们之间的差异。
SameType 和 SameValue
在了解 JavaScript 提供的这些比较/判断方法前,我们需要了解其内部提供的 SameType(x, y) 和 SameValue(x, y) 两个抽象方法。

不难看出 SameType 是完全的对类型进行对比,如果类型一致则返回 true,否则返回 false。
对于 SameValue 则是在 SameType的前提上对具体的值进行判断,其中对 Number 类型和 非Number 类型做了区分。其中:
Number中是对NaN+0-0一类的特殊值做了处理- 非
Number类型中其实就是对他们的比较做出了规范的定义


Strictly Equal

我们首先看严格相等,规范中首先判断的是类型,如果类型不一致,则直接不想等,后续则使用 Numer.equal 对数字类型进行判断。
值得注意的是,
Number::equal和Number::sameValue对于NaN+0-0的判断:
Number::equal中,一侧为NaN则直接为false,一侧为+0一侧为-0认为是 trueNumber::sameValue中,两侧同时为NaN返回true,一侧为+0一侧为-0返回false即:sameValue相对equal比较严格。

Loosely Equal

宽松相等的话,当类型一致的话判断方式就直接沿用了 Strictly Equal,后续都是对类型不一致时情况的处理。
可以看到大致逻辑是:
undefined和null- 当一侧为
Number/BigInt时,另一侧则会转换成Number/BigInt类型 - 当一侧为
Boolean类型的时候,就会将Boolean转换成Number在重新使用loosely equal判断 - 如果有一侧为对象的话,则将其会转换成原始值后调用
loosely equal比较 - 对于一侧为
Number一侧为BigInt时,如果一侧不是有限值,则直接返回false
Object.is

这里直使用了上面的 SameValue 进行判断,而且也没有其他特殊情况的处理。
isNaN

首先将传入的参数做了转换处理,然后判断转换后的值是不是 NaN,是则返回 true。
提示这里说,判断
X是否为NaN的可靠方法是使用形式为X !== X的表达式。当且仅当X为NaN时,结果才为真。 但是需要先排除X是对象的前提(即X需要是原始值)。
Number.isNaN

还是比较简洁的,需要注意的就是 Notes 提到的,与 isNaN 的区别在于: isNaN 会把参数做一次转换.
至此,总结了这几种比较方式,本质上还是通过 SameType SameValue 及其他底层的抽象方法和一些具体情况
进行处理。需要注意的可能就是一些特殊情况以及特殊情况对于的转换逻辑。