在est5中开发者使用对象属性来模拟。set多用于检查键的存在,map多用于提取数据。es6
{ let set = Object.create(null) set.foo = true; //检查属性是否存在 if (set.foo) { //其余操做 } let map = Object.create(null); map.foo = '一个值'; let val = map.foo; console.log('map-->:', val); //map-->:一个值' }
在简单状况下将对象做为map和set来使用都是可行的,可是一旦接触到对象属性的局限性,此方式就会遇到更多的麻烦。数组
{ let map1 = Object.create(null), key1 = {}, key2 = {}; map1[key1] = 'foo'; console.log('key2-->:', map1[key2]); let map2 = Object.create(null); map2.count = 1; //是想检查count的存在,仍是非零值? if (map2.count) { //... } }
map1[key1]和map1[key2]引用了同一个值。因为对象属性只能是string,又由于对象默认的string表达形式是'[object object]'。致使key1和key2被转换为同一个字符串。map2中count的用法存在歧义。该if语句内的代码都会被执行由于1被隐式转换为true。然而count的值为0则会被隐式转为false。在大型应用中这类问题都是难以确认,难以调试的。这也是新增set和map类型的缘由。set类型是一种无重复值的有序列表。set容许对它包含的数进行快速访问,从而更有效的追踪各类离散值。调试
使用new set()来建立。调用add()方法向集合中添加元素,访问集合的size属性获取集合数量。code
{ let set = new Set(); set.add(5); set.add('5'); console.log('typeof set-->:', typeof set) console.log('set-->:', set) console.log('size-->:', set.size) }
set不会使用强制类型转换来判断值是否重复,这意味着set能够同时包含number(5)和string(5),惟一的例外-0和+0在set中被断定是相等的,若是向set集合中添加多个对象,则他们之间彼此独立。对象
{ let set = new Set(); let key1 = {}; let key2 = {}; set.add(key1); set.add(key2); console.log('typeof setobject-->:', typeof set) console.log('setobject-->:', set) console.log('size-->:', set.size) }
因为key1和key2不会被转换为字符串,因此在set内部是不一样的项,若是他们被转化为字符串,那么都会等于"[object object]",若是屡次调用add()并传入相同的值做为参数。那么后续的调用会被忽略。索引
{ let set = new Set(); set.add(5); set.add('5'); set.add(5); console.log('typeof set-->:', typeof set) console.log('set-->:', set) console.log('size-->:', set.size) }
第二次重复传入numner(5)并不会被添加到set集合中,那么size的属性值仍是为2。也可使用数组来初始化set集合。集合一样会过滤重复的值。开发
{ let set = new Set([1, 2, 3, 4, 5, 5, 5, 5, 5, 5]); console.log('size-->:', set.size); }
经过has()能够检测set集合中是否存在某个值。字符串
{ let set = new Set(); set.add(5); set.add('6'); console.log('set has-->:', set.has(6)); console.log('set has-->:', set.has('6')) console.log('set has-->:', set.has(5)) console.log('set has-->:', set.has('5')) }
set集合中相同的number和sting并不会返回true。调用delete()方法能够移除set中的某一个值,调用clear()方法能够移除全部值。get
{ let set = new Set(); set.add(5); set.add('6'); console.log('set has-->:', set.has('6')); set.delete('6') console.log('set has-->:', set.has('6')) console.log('size-->:', set.size) set.clear(); console.log('size-->:', set.size) }
set集合简单易用,能够有效的跟踪多个独立有序的值。string
set集合和数组的forEach相似,运行机制也比较相似。forEach()方法的回调接收3个参数:
1.集合中索引的位置。
2.被遍历参数的值
3.集合自己
{ let set = new Set(['a', 'b', 'c', 'd', 'e']); set.forEach((k, val, owner) => { console.log('set-forEach-k-->:', k); console.log('set-forEach-val-->:', val); console.log('set-forEach-owner-->:', owner); }) }
将数组转换为set集合的过程很简单,须要给set集合传入数组便可。将集合转回数组,只须要使用展开运算符便可。
{ let arr = [1, 2, 3, 4, 5, 5, 5, 5, 5, 5]; let set = new Set(arr); let newArr = [...set]; //ps: 代码行数太多能够压缩下 let newArr2 = [...new Set([1, 2, 3, 4, 5, 5, 5, 5, 5, 5])]; console.log(newArr, newArr2) }
map类型是键值对的有序列表,键和值均可以是任意类型,能够调用set()方法传递一个键和一个关联的值,来给马屁添加项;此后使用键名来调用get()方法获取对应的值。
{ let map = new Map(); map.set('title', 'es6'); map.set('year', 2016); console.log('map-title-->', map.get('title')) console.log('map-year-->', map.get('year')) }
map和set共享了几个方法。如下的方法和属性map和set上都存在:
1.forEach(val, k, owner): 遍历map
2.has(key):判断指定的键值是否存在
3.delete(key):移除map中键以及对应的值
4.clear():移除map中全部的键和值
5.size:指明包含多个键值对。
{ let map = new Map(); map.set('title', 'es6'); map.set('year', 2016); map.forEach((val, k, owner) => { console.log('map-forEach-k-->:', k); console.log('map-forEach-val-->:', val); console.log('map-forEach-owner-->:', owner); }) console.log('map-size-->:', map.size); console.log('map-has-->:', map.has('title')); map.delete('title'); console.log('map-->:', map); map.clear(); console.log('map-->:', map); }
es6正式将set与map引入。在此以前每每使用对象来模拟,可是因为与对象属性有关的限制,这么作会常常遇到问题。这里并无弱引用weakset和weakmap,有这方面须要的能够本身去查阅