等式算法 equality algorithms
目前在es6的草案中,有4种等式算法
- Abstract Equality Comparison (
==) - Strict Equality Comparison (
===): used byArray.prototype.indexOf,Array.prototype.lastIndexOf, andcase-matching - SameValueZero: used by
TypedArrayandArrayBufferconstructors, as well asMapandSetoperations,并被用于es2016中的includes方法 - SameValue: used in all other places
抽象(非严格)等于 ==
抽象相等(“loose equality”, "double equals"),使用两个等号 ==
相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。在转换后(等式的一边或两边都可能被转换),最终的比较方式等同于全等操作符 === 的比较方式。 相等操作符满足交换律。
NaN == NaN // false, 原始类型都往数字方面转换,所以遇到NaN就无效了。
NaN == undefined // false
null == undefined // true, 都转成数字0
undefined == undefined // true, 都转成数字0
null == null // true, 都转成数字0
1 == '1' // true, 都转成数字1
+0 == -0 // true, 都转成数字0
所有的对象都与 undefined 和 null 还有NaN不相等。但是 null和undefined两个会相等。
原始类型在不同的类型进行转换时,基本是转换成数字。
对象类型在进行转换时,基本都通过toString() 和 valueOf() 方法转换成原始类型数据。
严格等于 ===
全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。如果两个被比较的值具有不同的类型,这两个值是不全等的。否则,如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。
NaN === NaN // false
NaN === undefined // false
null === undefined // false
undefined === undefined // true
null === null // true
1 === '1' // false
+0 === -0 // true
sameValue 同值相等
同值相等由Object.is 方法提供。确定两个值是否在任何情况下功能上是相同的。
Object.is(NaN, NaN) // true
Object.is(NaN, undefined) // false
Object.is(null, undefined) // false
Object.is(undefined, undefined) // true
Object.is(null, null) // true
Object.is(0, +0) // true
Object.is(-0, +0) // false
Object.is(0, -0) // false
具体算法如下
基本就是在严格等于的基础上,改动了下面两个判断:+0 不等于 -0 , NaN 等于 NaN。polyfill代码如下:
function(x, y) {
// SameValue algorithm
if (x === y) { // Steps 1-5, 7-10
// Steps 6.b-6.e: +0 != -0
return x !== 0 || 1 / x === 1 / y;
} else {
// Step 6.a: NaN == NaN
return x !== x && y !== y;
}
};
零值相等
与同值相等类似,只不过会认为+0 与 -0 相等。polyfill代码如下
function sameValueZero(x, y) {
return x === y || (typeof x === 'number' && typeof y === 'number' && isNaN(x) && isNaN(y));
}
浙公网安备 33010602011771号