Open
Description
相等性判断
Set
去重判断采用的是0值相等
判断算法,额这个是什么,相等判断不都是用==
或者===
么?查了下原来是ES6新引入的相等判断算法:
- 同值相等(SameValue);
- 0值相等(SameValueZero);
同值相等 & Object.is
判断同===
(类型+值一起判断), 但是特殊处理了NaN, 0, -0
:
console.log(NaN === NaN) // false
console.log(NaN == NaN) // false
console.log(Object.is(NaN, NaN)) // true
console.log(0 === -0) // true
console.log(0 == -0) // true
console.log(Object.is(0, -0)) // false
总结一句话:只有“长”的一样的值就是相等的(当然了0
和+0
是相等的)。
ES6的Object.is
实现了该算法。
0值相等
跟同值相等
算法一致,区别在于0值相等
中0等于-0。目前没有专门的方法实现该算法,但ES6一些API在内部使用该算法:
- Set判断value是否相等;
- Map判断key是否存在;
- Array.prototype.includes
var s = [...new Set([0, -0, NaN, 1, NaN])] // [0, NaN, 1]
严格相等===
ES2015之前只有严格相等和==
。
- 不进行类型转换,不同类型就不相等;
- 值类型比较值,引用类型比较引用。
NaN === NaN
为false。
ES5引入的方法Array.prototype.indexOf/lastIndexOf
采用这个相等策略。
再说下==
==
相等判断算法会涉及隐式类型转换,不提倡使用(一是乱,二是慢)。这里在总结下类型转换的规则:
- 相同类型的直接判断值(同
===
);
这里的类型是typeof
的结果值
console.log([] == {}) // false,都是对象,等价console.log([] === {})
null
和undefined
值不会发生类型转换,但是null == undefined
为true
,除了这个他俩跟其他类型都不相等;
null
,undefined
没有封装类型,也没有方法(不存在valueOf
,toString
方法)
console.log(null == undefined) // true
console.log(null == 0) // false
console.log(null == false) // false
- 对象转成基本类型(ToPrimitive)参与
==
比较;
先调用valueOf
方法,没有定义该方法的调用toString
方法。
var a = {
valueOf() {
return 1
}
}
var b = {
valueOf() {
return 1
}
}
var c = {
toString() {
return 1
}
}
console.log(a == 1) // true
console.log(b == 1) // true
console.log(c == 1) // true
console.log(a == b) // false,都是对象,并不会进行ToPrimitive
- 基本类型还不是相同类型,则都转成
Number
进行比较,即String
和bool
不会互转,都会统一转成Number
。
0 == String('0') // true, String('0')会先转成'0'
0 == '0' // true
0 == false // true
false == '0' // true