这是我参与更文挑战的第22天,活动详情查看:更文挑战
[重学JavaScript系列文章连载中...]
背景
ES6的Set集合是一种包含多个非重复值的有序列表,值与值如果相同,则会自动过滤重复值。它可以用来过滤数组中的重复元素,但是Set集合并不是数组的子类,所以不能通过索引直接访问集合中的值,只能通过has()检测元素是否在集合中,或者通过size()检测集合中值的数量,同时它支持forEach()或者遍历器来处理集合中的每个值。
Map是多个键值对组成的有序集合,键名支持任意数据类型,同时Map也是不允许存在重复值,对键名会存在过滤。
那Set和Map是怎么过滤键值对的?我们通常比较值,有两种方式用“==”或者“===”。
附:对Set不熟的可以前往改文字看看
ES6既有Set,为何还要有Weak Set集合?
==运算符
“==”运算符在判断相等时,如果两边的变量不是同一类型,会进行强制转换。这会导致(""==false)为true。
===运算符
“===”运算符只有在无需类型转换运算数就相等的情况下,才返回true。其将+0和-0视为相等,Number.NaN与NaN视为不相等。
学过Set和Map我们都知道,在这两集合中1和“1”是不会被过滤,且NaN值会被过滤,只允许存在一个。那么上述两种运算符是不符合了。
Object.is()
该用于判断两个值是否为同一值。而Set和Map集合便是用此方法进行判断,它的用法如下:
// value1:被比较的第一个值 value2:被比较的第二个值
Object.is(value1,value2)
Object.is()判断两个值是否同一值的规则如下:
-
都是undefined
-
都是null
-
都是true或false
-
都是相同长度的字符串且相同字符串顺序排列
-
都是相同对象(对象同一个引用)
-
都是数字且
-
都是+0
-
都是-0
-
都是NaN
-
或都是非零而且非NaN且为同一个值
-
看完它两值相等的规则,很好的满足Set和Map集合过滤重复值的需求点。
Polyfill
最后实现下Object.is的Polyfill。
if(!Object.is){
Object.is = function(x,y){
if(x===y){
// 满足上述的1~6.2和6.4点的判断
// 1/x === 1/y :判断的是+0和-0
return x!==0 || 1/x === 1/y
}else{
// 此处判断的是x和y是否都为NaN
return x!==x && y!==y
}
}
}
至此关于类型相等可以灵活运用了。