Es6
中新增了两种数据集合 Set
和 Map
。
7-1.Set
Set
是内部元素不重复存在的可迭代数据集合。
7-1-1.Set的创建
js
var set = new Set()
// Set实例上有size属性 对应的是数组的length属性 表示该集合的数据长度 初始为0
console.log(set.size)
// 1.添加元素
set.add('hello')
set.add('world')
// 重复添加的话 不会起作用
set.add('hello')
// 2.移除元素
set.delete('world')
// 3.是否包含某一元素
console.log(set.has('hello'))
console.log(set.has('world'))
// 4.清空集合
set.clear()
7-1-2.Set与数组
js
// 1.数组转化为Set
var list = ['i', 'love', 'i', 'do']
var set = new Set(list)
// 由于Set实例内的数据是不可重复 所以Set实例会自动对数组进行去重
console.log(set.size)
console.log(set) // Set(3) {'i', 'love', 'do'}
// 2.Set转化为数组
// 由于Set实例实际是可迭代的 所以我们要借助`展开运算符...`
var newList = [...set]
console.log(newList) // ['i', 'love', 'do']
7-1-3.Set的遍历
对应于数组的 forEach
方法,Set
的遍历也有对应的一个 forEach
方法。
js
var set = new Set(['i', 'love', 'my', 'job'])
set.forEach(function(value, key, currentSet) {
/*
i i Set(4) {'i', 'love', 'my', 'job'}
love love Set(4) {'i', 'love', 'my', 'job'}
my my Set(4) {'i', 'love', 'my', 'job'}
job job Set(4) {'i', 'love', 'my', 'job'}
*/
console.log(value, key, currentSet)
// 这里的this指向window
console.log(this)
}, this)
结合这段 JS
代码,来描述下 Set
的 forEach
方法的使用:
callback
value
值key
键。但由于集合对象没有索引,也就是没有key
,这里会与value
相等。这是为了看起来与数组的forEach
方法使用一致。currentSet
当前遍历的Set
集合。
thisArg
- 如果提供了一个
thisArg
参数给forEach
函数,则参数将会作为回调函数中的this
值。否则this
值为undefined
。回调函数中this
的绑定是根据函数被调用时通用的this
绑定规则来决定的。
- 如果提供了一个
7-1-4.WeakSet
在讨论 WeakSet
之间,我们需要先了解下垃圾回收。
js
// 当我们声明变量时 变量与目标对象会建立引用关系
var obj = {
name: 'yxp'
}
// 当我们打破建立的引用关系 那么{ name: 'yxp' }会处于“孤立无援”的状态 就会被浏览器回收 从内存中清除掉
obj = null
接下来,我们以数组为例:
js
var obj = {
name: 'yxp'
}
var list = []
list.push(obj)
// 虽然打破了obj与目标对象之间的引用关系 但数组项与目标对象的引用关系依然保留着 所以这时并不会回收清除
obj = null
在 WeakSet
的情况下:
js
var tom = { name: 'jack' }
var jerry = { name: 'jerry' }
var weakSet = new WeakSet()
weakSet.add(tom)
weakSet.add(jerry)
// 检查
console.log(weakSet.has(tom))
console.log(weakSet.has(jerry))
// 将tom的引用删除
tom = null
// 此时weakSet中也不会再继续保存tom tom会被垃圾回收机制清除 但由于我们无法确定浏览器对于该机制的具体执行时机 所以下列代码有可能依然是true 但按正常推断来说 应该是false
console.log(weakSet.has(tom))
总结:
- 与
Set
类似,但是我们只能向WeakSet
添加对象(而不能是原始值)。 - 对象只有在其它某个(些)地方能被访问的时候,才能留在
set
中。 - 跟
Set
一样,WeakSet
支持add
,has
和delete
方法,但不支持size
和keys()
。 WeakSet
不支持迭代。不能使用forEach
。
7-2.Map
Map
是一种储存着许多键值对的有序列表。
其中的键名和对应的值支持所有的数据类型。
7-2-1.Map的创建
js
var map = new Map()
// 1.添加元素
map.set('id', 19)
map.set('name', 'yxp')
// 重复添加的话 不会起作用
map.set('name', 'yxp')
// 相比 Set, Map的元素我们可以单个访问
console.log(map.get('id'))
// 2.移除元素
map.delete('name')
// 3.是否包含某一元素
console.log(map.has('id'))
console.log(map.has('name'))
// 4.清空集合
map.clear()
7-2-2.Map与数组
创建 Set
时,可以利用数组进行初始化设置。
而对于 Map
,我们也可以使用数组(二维数组)。
js
var map = new Map([['id', 19], ['name', 'yxp'], [{}, '空对象']])
console.log(map)
之所以是二维数组,是因为 Map
的键值要支持所有数据类型。只有在数组中,才能保留这种特性。
如果是对象键值对的方式,键只会是字符串类型。
7-2-3.Map的遍历
同 Set
的遍历方式相同,Map
也有 forEach
方法。
js
var map = new Map([['id', 19], ['name', 'yxp']])
var thisArg = {
description: '这个对象是thisArg'
}
map.forEach(function (item, index, currentMap) {
console.log(item, index, currentMap)
console.log(this)
}, thisArg)
7-2-4.WeakMap
与 WeakSet
类似,WeakMap
也可以有效的解决的内存泄漏的问题。
js
var tom = { name: 'Tom' }
var jerry = { name: 'Jerry' }
var weakMap = new WeakMap()
// 支持 set get has delete,不支持clear size forEach
weakMap.set(tom, 'Tom')
weakMap.set(jerry, 'Jerry')
console.log(weakMap)
// 将引用清除
tom = null
// 检测是否还存在
console.log(weakMap.has(tom))
总结:
- 与
Map
类似,但是我们只能向WeakMap
添加对象(而不能是原始值)。 - 对象只有在其它某个(些)地方能被访问的时候,才能留在
map
中。 - 跟
Map
一样,WeakMap
支持set
、get
、has
和delete
方法,但不支持size
。 WeakMap
不支持迭代。不能使用forEach
。