Js中的MapSet类型
Posted kula
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Js中的MapSet类型相关的知识,希望对你有一定的参考价值。
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中的MapSet类型的主要内容,如果未能解决你的问题,请参考以下文章