开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情
目录
- 不重复集合 Set WeakSet
- 键值对集合 Map WeakMap
- 练习
Set
Set对象,类似数组
- Set本身是一个构造函数
- Set对象的实例属性和实例方法
- Set使用场景: 数据去重
- Set遍历
- Set判断数据是否重复,类似 === 全等,全等的数据不能重复添加,NaN是个例外,Set将NaN视为相同;
- 添加目标是表达式时,会先运算,再以结果作为Set成员添加进去;
const demo = new Set()
typeof(demo)
// `Set`本身是一个构造函数
// `Set`函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数
new Set(document.querySelectorAll('div'))
function demo(){
new Set(arguments)
}
// 实例属性
demo.size
// 实例方法
demo.add({})
demo.add({}) // 不相等
demo.add([])
demo.add([]) // 不相等
demo.add(NaN)
demo.add(NaN) // 相等
demo.add(1)
demo.add('1') // 不相等
demo.add(null)
demo.add(null) // 相等
demo.add(undefined)
demo.add(undefined) // 相等
demo.add(1 == '1')
demo.add(1 == 1)
demo.add(true) // 都是true, 相等,保存最终值false
demo.add(1 === '1')
demo.add(false) // 都是false, 相等,保存最终值false
demo.add('') // 保存空字符
demo.add((1,2,3)) // 保存 3
demo.has({})
demo.has(1 == '1')
demo.delete('')
demo.clear()
// 转数组
Array.from(demo);
[...demo]
//数组去重
Array.from(new Set([1,1,2,2,3,4]));
// set 能满足
遍历顺序就是插入顺序, 因为Set只能通过add或者初始化时添加,而普通数组有多中添加方法,可改变元素index。
const arr = [2,3,4]
** `keys()`,`values()`,`entries()` **
Object.keys(arr)
Object.values(arr)
Object.entries(arr)
demo.keys()
demo.values()
demo.entries()
for (let x of demo) {
console.log(x);
}
demo = new Set([NaN, [], {}, null, undefined, 1, '1', ()=>{}, '', ' '])
demo.forEach((value, key) => console.log(key, key == value)) // 第一个返回false, 其余都是true
[...demo]
// `...`内部使用`for...of`循环,所以也可以用于 Set 结构
WeakSet
- WeakSet 是一个构造函数
- WeakSet对象实例方法;
- WeakSet的元素只能是对象,不论是普通对象还是方法对象;
- 处理对象,任何类型的数据都不能成为WeakSet的成员,包括Symbol类型 和 null;
// 构造函数
// 任何具有 Iterable 接口的对象,都可以作为 WeakSet 的参数
// WeakSet 的成员只能是对象
let ws = new WeakSet()
typeof(ws)
const b = [1,2]
ws.add()
ws = new WeakSet(b)
ws.add(b)
// 实例方法
ws.add({})
ws.delete(b)
ws.has(b)
// 弱连接
// 不能遍历,因为是弱映射,不参加内存回收,所以指不定什么时候,数据就消失了
(function(){
var a = [1];
demo4.add(a);
console.log(ws)
})()
// 匿名函数执行完,立即销毁,函数作用域内的a变量也消失,ws存的数据也就消失了
console.log(ws)
Map
补充对象取值
// 补充 对象取值
const person = {
name: 'cc'
}
person.name // 内部转换 person.name ===> person['name'] ==》 拿到键名为'name'的键值
// 普通对象
const p = {name: 'cc'}
const obj = {}
obj[p] = 'name'
obj[p] == obj['[object Object]']
// obj[p] ===> obj[p.toString()] ==> obj['[object Object]'] ===》 实际上 存的键名是'[object Object]'
Map知识
- Map键值对的集合,键名可以是对象;键名的不重复规则和set的不重复规则一样;
- 全等的键名名不能重复添加,NaN是个例外,虽然NaN!==NaN,但Map将NaN视为相同;
- Map作为构造函数
- 属性和实例方法;
- 遍历方法;
- 使用场景: 数据存储
- Map Set 数组 Iterator Json相互转换;
// 键值集合
// 对象类型键名,必须是是同一个对象,否则,被当多两个键名
const objKey = [1,2,3]
objKeyCopy = objKey
// objKey 和 objKeyCopy 是同一个键名
// objKey 和 [1,2,3] 不是同一个键名
// 构造函数
// 参数: 不仅仅是数组,任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构
map1 = new Map([
['name', '张三'],
['title', 'Author']
]);
// 非数组,但具有Iterator接口
new Map( new Set([['foo', 1],['bar', 2]]) )
// 属性
const map = new Map()
map.size // 类似数组的arr.length
// 实例方法
map.set(key, value)
map.set('key', 1)
// 链式写法
map.set(1, 'a').set(2, 'b').set(1, 'c')
// 同一个键名重复赋值,后值覆盖前值;
map.get(key) // 返回value, 找不到返回undefined
map.has(key) // true false
map.delete(key) // true false
map.clear()
// 遍历方法
map.keys()
map.values()
map.entries()
map.forEach((value, key, map)=>{})
forof
typeof map.keys() // 'object'
demo.keys() instanceof Array // false
demo.keys().map() // TypeError: demo.keys(...).map is not a function
// 返回值类型不知数组,需要转换为数组,才能使用数组方法;
// 数据结构转换
[...map] // map ===》 Array
new Map(Array) // Array ===》 map
map.forEach((value, key, map)=>{obj[key] = value}) // map ===》 Object
new Map(Object.entries(Object)) // // Object ===》 map
JSON.stringify(数组/对象) map ===》数组/对象 ===》 JSON
toMap(JSON.parse(JSON)) JSON ===》 数组/对象 ===》 map
WeakMap
- 弱关联集合;只有键名弱关联,键值仍是正常引用
- 类似Map,不同点:WeakMap只接受对象作为键名(
null除外),不接受其他类型的值作为键名; - 键名不参与垃圾回收机制;
- 实例方法;
// 弱应用,键名随时可能消失,所以
// 除了以下四个方法,其他map的方法都不能用;
get()
set()
has()
delete()
演练playground
- 添加数据
// Set
const demo = new Set()
const arr = [1,2,3]
demo.add([1,2,3])
demo.add(arr)
demo.add(1 - '0')
demo.add(1 + '0')
demo.add(Infinity/0)
demo.add(Infinity/-0)
demo.add(Infinity/-9)
//Map
const demo2 = new Map()
demo2.set(undefined, 1)
demo2.set(null, 1)
demo2.set(false, 1)
demo2.set(true, 1)
demo2.set(NaN, 1)
demo2.set((1,2,3), 1)
demo2.set(-0, 1)
demo2.set(0, 1)
demo2.set('', 1)
- 判断是否是Set Map数据类型
// instanceof
demo instanceof Map
demo instanceof Set
// Object.prototype.toString.call()
Object.prototype.toString.call(demo) // '[object Set]' 或 '[object Map]‘
//constructor
demo.constructor === Map
demo.constructor === Set