Js中的Map、Set类型
2021/5/19 18:26:36
本文主要是介绍Js中的Map、Set类型,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Map、Set类型
1.Map(映射)
创建同时实例化,传入可迭代对象(需要包含的是一个含键/值对数组),会按顺序插入
const m1 = new Map([ ["key1", "val1"], ["key2", "val2"], ["key3", "val3"] ]); console.log(m1.size); // 3 //size属性返回大小(没有length) console.log(m1.has("key4")); // false console.log(m1.get("key4")); // undefined m1.set("key4", "val4") .set("key5", "val5"); // set()返回映射本身,因此可以连续set m1.delete("key5"); //删除一对键/值 m1.clear(); //删除全部
与Object只能使用数值、字符串或符号作为键不同,Map可以使用任何JavaScript数据类型作为键。
keys()、values()、entries()(默认 [Symbol.iterator])分别返回 键、值、键/值数组的迭代器
(系统的迭代器默认也实现了iterable接口 所以可以给for...of ,Array.from传迭代器对象)自己定义的类型则需自己实现
class A{ constructor(id){ this.id=id; } [Symbol.iterator](){ let max = this.id; let count = 0; return { next(){ if(count<max){ count++; return {done:false,value:count-1}; }else{ return {done:true}; } }, [Symbol.iterator](){return this;} }; } } let a = new A(5);
2.WeakMap
弱映射中的键只能是Object或者继承自Object的类型,值的类型没有限制。
const key1 = {id: 1}, key2 = {id: 2}, key3 = {id: 3}; // 使用嵌套数组初始化弱映射 const wm1 = new WeakMap([ [key1, "val1"], [key2, "val2"], [key3, "val3"] ]);
也具备set()、get()、has()、delete()、clear()方法。
1.弱键
弱键是指这些键不属于正式的引用,不会阻止垃圾回收。
const wm = new WeakMap(); wm.set({}, "val");
由于没有标识符或对象有 “{} ” 的引用,所以下次垃圾回收时会回收这个键值对
2.不可迭代键
WeakMap没有也不允许迭代操作
3.如何使用弱映射
-
私有变量:原理是将私有变量存于弱映射中,以对象为键(防止内存泄漏,不影响垃圾清理),放在WeakMap成员对象中
例子中 id的键固定为符号Symbol(id) ,其他私有变量可以自定义
let User = (() => { const w = new WeakMap(); class User{ constructor(id){ this.id = id; if(id==undefined) this.id = 0; this.idProperty = Symbol(id); this.setId(this.id); } setPrivate(property,value){ let o = w.get(this) || {}; o[property] = value; w.set(this,o); } getPrivate(property){ let o = w.get(this); if(o!==undefined){ return o[property]; } return undefined; } setId(id){ this.setPrivate(this.idProperty,id); } getId(){ return this.getPrivate(this.idProperty); } } return User; })(); const user = new User("01"); user.getId();
-
DOM节点关联数据
const m = new Map(); const loginButton = document.querySelector('#login'); // 给这个节点关联一些元数据 m.set(loginButton, {disabled: true});
如果dom节点被删除了,但由于Map中还保存着引用,所以对应的DOM节点仍然会逗留在内存中。
如果使用Map则不会发生
3.Set(集合)
// 使用数组初始化集合 const s1 = new Set(["val1", "val2", "val3"]); alert(s1.size); // 3 无length属性 // 使用自定义迭代器初始化集合 const s2 = new Set({ [Symbol.iterator]: function*() { yield "val1"; yield "val2"; yield "val3"; } }); console.log(s2.size); // 3 console.log(s1.has("val4")); // false 布尔值 s1.add("val4") .add("val5"); //add()返回集合本身,因此可以连续add s1.delete("val5"); // 删除值 s1.clear(); // 销毁所有值
集合中的元素不能重复 所以 add()和delete() 操作是幂等的
Set也可以迭代 keys() === values() (默认)都迭代值 ,entries() 迭代格式为[value, value]
也可对Set进行增强实现集合操作
class XSet extends Set { union(...sets) { return XSet.union(this, ...sets) } intersection(...sets) { return XSet.intersection(this, ...sets); } difference(set) { return XSet.difference(this, set); } symmetricDifference(set) { return XSet.symmetricDifference(this, set); } cartesianProduct(set) { return XSet.cartesianProduct(this, set); } powerSet() { return XSet.powerSet(this); } // 返回两个或更多集合的并集 static union(a, ...bSets) { const unionSet = new XSet(a); for (const b of bSets) { for (const bValue of b) { unionSet.add(bValue); } } return unionSet; } // 返回两个或更多集合的交集 static intersection(a, ...bSets) { const intersectionSet = new XSet(a); for (const aValue of intersectionSet) { for (const b of bSets) { if (!b.has(aValue)) { intersectionSet.delete(aValue); } } } return intersectionSet; } // 返回两个集合的差集 static difference(a, b) { const differenceSet = new XSet(a); for (const bValue of b) { if (a.has(bValue)) { differenceSet.delete(bValue); } } return differenceSet; } // 返回两个集合的对称差集 static symmetricDifference(a, b) { // 按照定义,对称差集可以表达为 return a.union(b).difference(a.intersection(b)); } // 返回两个集合(数组对形式)的笛卡儿积 // 必须返回数组集合,因为笛卡儿积可能包含相同值的对 static cartesianProduct(a, b) { const cartesianProductSet = new XSet(); for (const aValue of a) { for (const bValue of b) { cartesianProductSet.add([aValue, bValue]); } } return cartesianProductSet; } // 返回一个集合的幂集 static powerSet(a) { const powerSet = new XSet().add(new XSet()); for (const aValue of a) { for (const set of new XSet(powerSet)) { powerSet.add(new XSet(set).add(aValue)); } } return powerSet; } }
4.WeakSet
弱集合中的值只能是Object对象
const val1 = {id: 1}, val2 = {id: 2}, val3 = {id: 3}; // 使用数组初始化弱集合 const ws1 = new WeakSet([val1, val2, val3]); 也拥有add()、has()、delete()、clear()方法,性质和Set类似。 - 弱值和WeakMap基本相同,不影响垃圾回收 - 也是不可以迭代的 - 给dom中的打标记时应用,比如在集合中的节点都禁用 ```javascript const disabledElements = new WeakSet(); const loginButton = document.querySelector('#login'); // 通过加入对应集合,给这个节点打上“禁用”标签 disabledElements.add(loginButton);
5.迭代与扩展
我们接触了有4种原生集合类型定义了默认迭代器:
- Array
- 定型数组
- Map
- Set
这意味着上述所有类型都支持顺序迭代,常见的处理语法有:
-
for...of
-
( ... ) 拓展操作符
let arr1 = [1, 2, 3]; let arr2 = [...arr1]; // 相当于分解为逗号分隔 console.log(arr1); // [1, 2, 3] console.log(arr2); // [1, 2, 3]
-
期待可迭代对象的构造函数
let map1 = new Map([[1, 2], [3, 4]]); let set1 = new Set(["v1", "v2"]);
-
Array.from() 方法
这篇关于Js中的Map、Set类型的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26怎么使用 nvm(Node Version Manager)下载并安装指定版本的 Node.js?-icode9专业技术文章分享
- 2024-11-26Vue CLI资料入门教程
- 2024-11-26Vue CLI资料入门教程
- 2024-11-26Vue3+Vite资料:新手入门教程详解
- 2024-11-26Vue3阿里系UI组件资料入门教程
- 2024-11-26Vue3的阿里系UI组件资料入门指南
- 2024-11-26Vue3公共组件资料详解与实战教程
- 2024-11-26Vue3公共组件资料详解与实战教程
- 2024-11-26Vue3核心功能响应式变量资料入门教程
- 2024-11-26Vue3核心功能响应式变量资料详解