【js】Set和Map数据结构
Set和Map数据结构
- Set
- WeakSet
- Map
- WeakMap
数组
,成员值都是唯一
的Set本身是一个构造函数,用来生成Set数据结构
let s = new Set([1])
console.log(s);
文章图片
- Set中可以接受具有
iterable
接口的其他数据结构 - 可以用
[...new Set(arr)]
数组去重 - Array.from(new Set(arr))也可
- constructor
size
let s = new Set([1, 2])
console.dir(s.__proto__.constructor === Set.prototype.constructor);
//true
console.log(s.size) //2
- size表示
成员数量
,类似于数组的length
属性
- 操作方法:add delete has clear
- 遍历方法:values keys entries forEach
1-操作方法
add(value)
添加值,返回Set本身
let s = new Set([1, 2]) let s1 = s.add(3) console.log(s, s1);
文章图片
detele(value)
删除值,返回布尔值
,确定删除成功
let s = new Set([1, 2]) let s1 = s.delete(1) console.log(s, s1);
文章图片
has(value)
返回布尔值
,确定是否有某个值,类似数组的includes
let s = new Set([1, 2]) let s1 = s.has(2) console.log(s, s1);
文章图片
clear()
清除所有成员,无
返回值
let s = new Set([1, 2]) let s1 = s.clear() console.log(s, s1);
文章图片
2-遍历方法
keys()
返回键名的遍历器
let s = new Set([1, 2, "a", "b"]) let s1 = s.keys() console.log(s1); for (const i of s1) { console.log(i); }
文章图片
values()
返回键值的遍历器
let s = new Set([1, 2, "a", "b"]) let s1 = s.values() console.log(s1); for (const i of s1) { console.log(i); }
文章图片
可以看出keys与values遍历出的值是相同的
entries()
返回键值对
let s = new Set([1, 2, "a", "b"]) let s1 = s.entries() console.log(s1); for (const i of s1) { console.log(i); }
文章图片
forEach()
使用回调函数遍历每个成员,无返回值
let s = new Set([1, 2, 3, 4]) s.forEach(x => { console.log(x * 2); //2 4 6 8 })
- WeakSet的成员只能是
对象
,否则会报错
let s = new WeakSet([1, 2, 3, 4]) console.log(s);
文章图片
- WeakSet中的对象为弱引用
- 不可遍历
- 没有
size
属性 - 方法:add delete has
let obj = { a: 1 } let s = new WeakSet([[0], [1]]) s.add(obj) console.log(s);
文章图片
对象
,一种更完善的Hash结构- Map构造函数
const set = new Set([["a", 1], ["b", 2]]) const map = new Map(set) console.log(map);
文章图片
Map可以接收一个具有
Iterator
接口且每个成员都是一个双元素数组的数据结构
Map上也有size
属性,表示成员数量
Map的键是与内存
绑定的,内存不一样则视为两个键,NaN视为同一个键
- 操作方法:set get has delete clear
- 遍历方法 keys values entries forEach
1-操作方法
set(key,value)
get(key)
添加成员 获取值 返回Map
const map = new Map() map.set("a", 1) console.log(map); console.log(map.get("a"));
文章图片
has(key)
返回布尔值,某个键是否在Map中
const map = new Map([["a", 1]]) let m1 = map.has("a") console.log(map, m1);
文章图片
delete(key)
删除一个键,返回布尔值
const map = new Map([["a", 1], ["b", 2]]) let m1 = map.delete("a") console.log(map, m1);
文章图片
clear()
清空所有成员,无放回值
const map = new Map([["a", 1], ["b", 2]]) let m1 = map.clear() console.log(map, m1);
文章图片
2-遍历方法
keys()
返回键名的遍历器values()
返回键值的遍历器entries()
返回键值对的遍历器forEach(callback,thisArg)
遍历Map的所有成员
遍历方法与Set大致相同,不再举例介绍Map与其他数据结构的转换
要注意的是for(let [key,value] of map)
等同于使用map.entries()
同样entries遍历器也可以赋值给这样的两个参数
- 数组
- 对象
- JSON
1.Map与数组的转换
- Map转数组
扩展符
操作
const map = new Map([["a", 1], ["b", 2]]) console.log([...map]); //[["a",1],["b",2]]
- 数组转Map
- 将数组写入Map构造函数中即可
let map = new Map( ["a", 0], [{ "b": true }, 2] ) console.log(map);
文章图片
2.Map与对象转换
- Map转对象
- Map的所有键都是字符串,可以将其转为对象
function toObj(map) { let obj = Object.create(null) for (let [k, v] of map) { obj[k] = v } return obj }//遍历map 将key value逐对赋值给一个对象 let map = new Map([ ["a", 1], ["b", 2] ]) console.log(toObj(map)); //{"a":1,"b":2}
- 对象转Map
- 遍历对象,用set的方式为Map添加键值对
function objToMap(obj) { let map = new Map() for (let k of Object.keys(obj)) { map.set(k, obj[k]) } return map } let obj = { a: 1, b: 2 } console.log(objToMap(obj)); // { "a" => 1 , "b" => 2 }
3.Map与JSON的转换
- Map转对象JSON
- Map的键名都是字符串
function toObj(map) { let obj = Object.create(null) for (let [k, v] of map) { obj[k] = v } return obj } function toObjJson(map) { return JSON.stringify(toObj(map)) } let map = new Map([ ["a", 1], ["b", 2] ]) console.log(toObjJson(map)); //'{"a":1,"b":2}'
先把Map转为对象,再用JSON序列化
- Map转数组JSON
- Map中键名有非字符串
function toObjJson(map) { return JSON.stringify([...map]) } let map = new Map([ [true, 1], [false, 0] ]) console.log(toObjJson(map)); //'[[true,1],[false,0]]'
先将Map转为数组,再用JSON序列化
- 对象JSON转Map
- 键名都为字符串
function objToMap(obj) { let map = new Map() for (let k of Object.keys(obj)) { map.set(k, obj[k]) } return map } function jsonToStrMap(json) { return objToMap(JSON.parse(json)) } let json = '{"a":1,"b":2}' console.log(jsonToStrMap(json)); //{"a" => 1 , "b" => 2}
先将json反序列换转为对象,再将对象转为Map
- 数组JSON转为Map
- JSON本身是一个数组,每个成员是包含两个元素的数组
function jsonToMap(json) { return new Map(JSON.parse(json)) } let json = '[[true,1],[false,0]]' console.log(jsonToMap(json)); // {true => 1 , false => 0}
先将JSON反序列化为数组,再将数组转为Map
区别
- WeakMap只接受对象作为键名
- 【【js】Set和Map数据结构】键名所指向的对象不计入垃圾回收机制
与WeakSet类似,对象的引用都是弱引用
没有size属性
没有
遍历的操作 即没有keys values entries forEach这些方法- 键名是若引用的,防止出现不确定性,因此统一规定不能取到键名
- 不能清空,没有clear方法
- 可用方法 set get has delete
对于WeakMap,适用于将DOM节点作为键名
推荐阅读
- 宽容谁
- 我要做大厨
- 增长黑客的海盗法则
- 画画吗()
- 2019-02-13——今天谈梦想()
- 远去的风筝
- 三十年后的广场舞大爷
- 叙述作文
- 20190302|20190302 复盘翻盘
- 学无止境,人生还很长