ES标准中的相等比较算法
1.抽象等式比较算法( The Abstract Equality Comparison Algorithm )
== 基于该算法
- 当类型相同时,直接比较值是否相等
- 类型若不相同,则首先转化为类型相同的值,再进行比较
只有一种情况推荐使用 == ,即判断一个值为 null 或 undefined 时,可以使用同时判断这两种情况。
let val1 = null;
let val2 = undefined;
console.log(val1 == undefined, val1 == null); // true true
console.log(val2 == undefined, val2 == null,); // true true
console.log( null == undefined); // true
因为类型转化的情况会导致对比的不确定性大大增加,除了上面一种情况,其他时候建议不要使用 == 。
补充:几种因为类型转换判断为 true 的情况
console.log( '1' == 1); // true
console.log( '' == 0 ); // true
console.log( '' == false); // true
console.log( 1 == true ); // true
console.log( 0 == false ); // true
console.log( [] == false ); // true
console.log( null == undefined); // true
更加详细的转换情况可以查阅 Loose equality using ==
2.严格相等比较算法( The Strict Equality Comparison Algorithm )
=== 基于该算法,这是最好理解的一种情况
- 当类型相同时,直接比较值
- 类型若不相同,直接判定为不相等
注意引用类型的对比:
let obj = { a: 1, b: 2 };
let copyObj = obj;
console.log(obj === copyObj); // true
console.log({} === {}); // false
引用类型实际比较的是栈中的地址
3.SameValue
Object.is 就是基于 SameValue 算法进行比较
直接说这种算法大家可能不太熟悉,我们直接与 === 做比较,除了下面两种情况,其余和 === 是一样的。
情况1:判断 +0,-0
console.log(+0 === -0); // true
console.log(Object.is(+0, -0)); // false
情况2:判断 NaN
console.log(NaN === NaN); // false
console.log(Object.is(NaN, NaN)); // true
NaN可谓是六亲不认,连自己本身用 === 判断都不相等,但是 Object.is 却能判断 NaN 相等
补充:如何判断一个值是否为 NaN
let val = NaN;
console.log(Number.isNaN(val)); // true
console.log(isNaN(val)); // true
Number.isNaN() 和 isNaN() 都能判断值是否为 NaN,但是二者本身还有些区别:
- Number.isNaN() 仅仅当值为 NaN 时才判断为 true
- isNaN() 会强制将值转换为数字为 NaN ,或者当前值为 NaN 时才判断为 true
let val1 = 'v';
let val2 = '1';
console.log(Number.isNaN(val1), Number.isNaN(val2)); // false false
console.log(isNaN(val1), isNaN(val2)); // true false
补充:几种 isNaN() 判断的情况
console.log(isNaN('')); // false
console.log(isNaN([])); // false
console.log(isNaN(false)); // false
console.log(isNaN(true)); // false
console.log(isNaN(null)); // false
console.log(isNaN(undefined)); // true ,注意 undefined 的情况返回是true
想要了解 NaN 更多可以查阅 全局属性 NaN
4.SameValueZero
未提供API,同样直接与 === 做比较,除了下面一种情况,其余和 === 是一样的。
情况1:判断 NaN
由于无直接 API 可用,但很多地方使用该对比算法,例如 js 中 Array 的 includes 方法,在这使用 includes 来进行对比演示
let arr = [NaN]
console.log(arr.includes(NaN)); // true
SameValueZero也可以判断 NaN 相等
想了解更加详细的比较算法,可以查阅 Equality comparisons and sameness
相同值对照表,可查阅 Sameness Comparisons