【JS特性】相等性判断

2021/09/08 18:16:04

判断方法

===

  1. 类型不同时为 false
  2. NaN 与任何值都不全等,包括它自己,即一方为 NaN 时为 false
  3. 对于非数值而言该值只与自身全等
  4. 对于数值:浮点数 0 不分正负,即 +0 === -0成立

全等算法

If Type(x) is different from Type(y), return false.
If Type(x) is Undefined, return true.
If Type(x) is Null, return true.
If Type(x) is Number, then
    If x is NaN, return false.
    If y is NaN, return false.
    If x is the same Number value as y, return true.
    If x is +0 and y is −0, return true.
    If x is −0 and y is +0, return true.
    Return false.
If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions); otherwise, return false.
If Type(x) is Boolean, return true if x and y are both true or both false; otherwise, return false.
Return true if x and y refer to the same object. Otherwise, return false.

特殊值比较

undefined === undefined; // true
null === null; // true
undefined === null; // false
(NaN ===
  NaN + // false
    0) ===
  -0; // true

==

  1. 比较前将两个比较的值转换为同一类型,转换后的比较方式等同于 ===
  2. 相等操作符满足交换律(左右双方调换不会影响最终结果)

相等操作符对于不同类型的值,进行的比较如下图所示(行为比较值 A,列为比较值 B):

B
UndefinedNullNumberStringBooleanObject
AUndefinedtruetruefalsefalsefalseIsFalsy(B)
NulltruetruefalsefalsefalseIsFalsy(B)
NumberfalsefalseA === BA === ToNumber(B)A=== ToNumber(B)A== ToPrimitive(B)
StringfalsefalseToNumber(A) === BA === BToNumber(A) === ToNumber(B)ToPrimitive(B) == A
BooleanfalsefalseToNumber(A) === BToNumber(A) === ToNumber(B)A === BToNumber(A) == ToPrimitive(B)
ObjectfalsefalseToPrimitive(A) == BToPrimitive(A) == BToPrimitive(A) == ToNumber(B)A === B

ToNumber(A) 尝试在比较前将参数 A 转换为数字

ToPrimitive(A)通过尝试调用 A 的A.toString()A.valueOf() 方法,将参数 A 转换为原始值(Primitive)

undefined == undefined; // true
null == null; // true
undefined == null; // true
NaN === NaN; // false

Object.isopen in new window()

行为与 === 相同,但是对于 NaN 和-0 和+0 进行特殊处理

Object.is(NaN, NaN); // true
Object.is(+0, -0); // false
Object.is(NaN, NaN); // true

三种比较方式对不同值的处理

xy=====Object.isopen in new window
undefinedundefinedtruetruetrue
nullnulltruetruetrue
truetruetruetruetrue
falsefalsetruetruetrue
"foo""foo"truetruetrue
00truetruetrue
+0-0truetruefalse
0falsetruefalsefalse
""falsetruefalsefalse
""0truefalsefalse
"0"0truefalsefalse
"17"17truefalsefalse
[1,2]"1,2"truefalsefalse
new String("foo")"foo"truefalsefalse
nullundefinedtruefalsefalse
nullfalsefalsefalsefalse
undefinedfalsefalsefalsefalse
falsefalsefalse
new String("foo")new String("foo")falsefalsefalse
0nullfalsefalsefalse
0NaNfalsefalsefalse
"foo"NaNfalsefalsefalse
NaNNaNfalsefalsetrue

规范中的相等、严格相等以及同值相等

在 ES5 中, ==open in new window 相等在 Section 11.9.3, The Abstract Equality Algorithmopen in new window===open in new window 相等在 11.9.6, The Strict Equality Algorithmopen in new window。(请参考这两个链接,他们很简洁易懂。提示:请先阅读严格相等的算法)ES5 也提供了 same-value 相等, Section 9.12, The SameValue Algorithmopen in new window ,用在 JS 引擎内部。除了 11.9.6.4 和 9.12.4 在处理数字上的不同外,它基本和严格相等算法相同。ES6 简单地通过 Object.isopen in new window 暴露了这个算法。

其他

  1. 全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。
  2. === 是 == 的子集