大统新闻信息网

介绍下Set、Map、WeakSet 和 WeakMap 的区别?

Set和Map的主要应用场景是数据重组和数据存储

Set是一个称为集合的数据结构,Map是一个称为字典的数据结构。

添加到ES6的新数据结构,类似于数组,但成员是唯一且无序的,没有重复值。

Set本身是一个构造函数,用于生成Set数据结构。

新集([iterable])

例如:

Const s=new Set()

[1,2,3,4,3,2,1] .forEach(x=> s.add(x))

对于(让我的s){

Console.log(i)//1 2 3 4

}

//从数组中删除重复的对象

设arr=[1,2,3,2,1,1]

[.新集(arr)] //[1,2,3]

Set对象允许您存储任何类型的唯一值,无论它们是原始值还是对象引用。

将值添加到Set时,不会发生类型转换,因此5和'5'是两个不同的值。内部设置确定两个值是否不同。使用的算法称为“相同值零相等”,它类似于精确相等运算符(===)。主要的区别在于** NaN等于它自己,而精确的等式算子认为NaN不等于它自己。 **

设set=new Set();

设a=NaN;

设b=NaN;

Set.add(一);

Set.add(B);

设置//设置{NaN}

设set1=new Set()

Set1.add(5)

Set1.add( '5')

Console.log([. set1])//[5,'5']

设置实例属性

构造函数:构造函数大小:元素数

设set=new Set([1,2,3,2,1])

Console.log(set.length)//未定义

Console.log(set.size)//3

设置实例方法

操作方法

添加(值):添加,相当于推入数组

删除(值):存在以删除集合中的值

Has(value):确定集合中是否有值

Clear():清空集合

设set=new Set()

Set.add(1)。新增(2)。新增(1)

Set.has(1)//true

Set.has(3)//假

Set.delete(1)

Set.has(1)//假

Array.from方法可以将Set结构转换为数组

Const items=new Set([1,2,3,2])

Const array=Array.from(items)

Console.log(数组)//[1,2,3]

//或

Const arr=[. items]

Console.log(arr)//[1,2,3]

遍历方法(遍历顺序是插入顺序)keys():返回包含集合中所有键的迭代器

Values():返回包含集合

中所有迭代器的一个

Entries():返回包含Set对象

中所有元素的键值对的迭代器

forEach(callbackFn,thisArg):用于对集合成员执行callbackFn操作。如果提供thisArg参数,则回调函数中的此参数将为此参数,并且没有返回值

设set=new Set([1,2,3])

Console.log(set.keys())//SetIterator {1,2,3}

Console.log(set.values())//SetIterator {1,2,3}

Console.log(set.entries())//SetIterator {1,2,3}

For(让set.keys()的项目){

CONSOLE.LOG(项目);

} //12 3

For(让set.entries()的项目){

CONSOLE.LOG(项目);

} //[1,1] [2,2] [3,3]

set.forEach((value,key)=> {

Console.log(键+':'+值)

})//1: 12: 23: 3

Console.log([. set])//[1,2,3]

默认情况下可以遍历Set,默认迭代器生成函数是values()方法

Set.prototype [Symbol.iterator]===Set.prototype.values //true

所以,Set可以使用map,filter方法

设set=new Set([1,2,3])

Set=new Set([. set] .map(item=> item * 2))

Console.log([. set])//[2,4,6]

Set=new Set([. set] .filter(item=>(item>=4)))

Console.log([. set])//[4,6]

因此,Set很容易实现Intersect,Union和Difference。

设set1=new Set([1,2,3])

设set2=new Set([4,3,2])

设intersect=new Set([. set1] .filter(value=> set2.has(value)))

设union=new Set([. set1, set2])

设差异=新设置([. set1] .filter(value=>set2.has(value)))

Console.log(交叉)//设置{2,3}

Console.log(union)//设置{1,2,3,4}

Console.log(差异)//设置{1}

WeakSet对象允许您在集合中存储弱引用对象

WeakSet和Set之间的区别:

WeakSet只能存储对象引用,而不能存储值,而WeakSet对象中存储的对象值可以弱引用Set对象。也就是说,如果没有其他变量或属性,垃圾收集机制不会考虑WeakSet对该对象的应用。通过引用此对象值,对象将被垃圾收集(无论对象是否仍存在于WeakSet中),因此WeakSet对象中有多少成员元素,具体取决于垃圾收集机制是否正在运行。数量可能不一致。在遍历结束后,某些成员可能无法获取它(通过垃圾回收),无法遍历WeakSet对象(ES6规定不能遍历WeakSet),并且无法获取它包含的所有元素。

属性:

构造函数:构造函数,任何具有Iterable接口的对象,都可以用作参数

Const arr=[[1,2],[3,4]]

Const weakset=new WeakSet(arr)

CONSOLE.LOG(weakset)

a00aed30ffbb47bba70eb38a132e88bc

方法:

Add(value):向WeakSet对象添加元素valuehas(value):确定WeakSet对象是否包含valuedelete(value):删除元素valueclear():清除所有元素,注意方法已过时

Var ws=new WeakSet()

Var obj={}

Var foo={}

Ws.add(窗口)

Ws.add(OBJ)

Ws.has(窗口)//true

Ws.has(富)//假

Ws.delete(窗口)//true

Ws.has(窗口)//假

集合和字典之间的区别:

共性:集合,字典可以存储非重复值的不同点:集合以[value,value]的形式存储元素,存储为[key,value]

Const m=new Map()

Const o={p:'haha'}

M.set(o,'content')

M.get(o)//content

M.has(o)//true

M.delete(o)//true

M.has(O)//假

任何具有Iterator接口且每个成员都是双元素数组的数据结构都可以用作Map构造函数的参数,例如:

Const set=new Set([

['foo',1],

['bar',2]

]);

Const m1=new Map(set);

M1.get('foo')//1

Const m2=new Map([['baz',3]]);

Const m3=new Map(m2);

M3.get('baz')//3

如果读取未知密钥,则返回undefined。

新地图()。get('asfddfsasadf')

//未定义

请注意,仅当Map结构是对同一对象的引用时,它才将其视为相同的键。对此要非常小心。

Const map=new Map();

Map.set(['a'],555);

Map.get(['a'])//undefined

上面代码的set和get方法,表面是针对相同的键,但实际上这是两个值,内存地址不一样,所以get方法无法读取键,返回undefined。

从上面可以看出,Map键实际上是绑定到内存地址,只要内存地址不一样,就算是两个键。这解决了同名属性冲突的问题。当我们扩展其他人的库时,如果我们使用该对象作为键名,我们就不必担心原作者属性的相同名称。

如果Map键是一个简单类型的值(数字,字符串,布尔值),那么只要两个值完全相等,Map就会将其视为一个键,例如0和-0是一个键,布尔值为true和字符串字符串true是两个不同的键。另外,undefined和null也是两个不同的键。尽管NaN并不完全等同于自身,但Map将其视为同一个密钥。

设map=new Map();

Map.set(-0,123);

Map.get(+0)//123

Map.set(true,1);

Map.set('true',2);

Map.get(true)//1

Map.set(undefined,3);

Map.set(null,4);

Map.get(undefined)//3

Map.set(NaN,123);

Map.get(NaN)//123

地图属性和方法

属性:

构造函数:构造函数size:返回字典中包含的元素数

Const map=new Map([

['name','An'],

['des','JS']

]);

Map.size //2

如何操作:

Set(key,value):向字典添加新元素get(key):按键查找特定值并返回has(key):确定字典中是否存在keydelete(key):从键中删除字典按键对应数据clear():删除此词典中的所有元素

遍历方法

Keys():返回迭代器中字典中包含的键名的所有值:values():返回字典中包含的所有值作为entries()的迭代器:返回迭代器forEach的所有成员():遍历字典所有成员

Const map=new Map([

['name','An'],

['des','JS']

]);

Console.log(map.entries())//MapIterator {'name'=>'An','des'=>'JS'}

Console.log(map.keys())//MapIterator {'name','des'}

Map结构的默认walker接口(Symbol.iterator属性)是entries方法。

Map [Symbol.iterator]===map.entries

//true

Map结构转换为数组结构。更快捷的方法是使用扩展运算符(.)。

对于forEach,请参阅示例

Const记者={

报告:函数(键,值){

Console.log('密钥:%s,值:%s',密钥,值);

}

};

设map=new Map([

['name','An'],

['des','JS']

])

map.forEach(function(value,key,map){

This.report(键,值);

记者);

//密钥:名称,值: An

//密钥: des,值: JS

在此示例中,forEach方法的回调函数的this函数指向报告者

与其他数据结构的互换

映射到数组

Const map=new Map([[1,1],[2,2],[3,3]])

Console.log([. map])//[[1,1],[2,2],[3,3]]

2.Array to Map

Const map=new Map([[1,1],[2,2],[3,3]])

Console.log(map)//Map {1=> 1,2=> 2,3=> 3}

3.Map to Object

由于Object的键名都是字符串,并且Map的键称为对象,因此非字符串键名在转换时将转换为字符串键名。

函数mapToObj(map){

设obj=Object.create(null)

对于(让地图的[键,值]){

Obj [key]=value

}

返回obj

}

Const map=new Map()。set('name','an')。set('des','JS')

mapToObj(map)//{name:'An',des:'JS'}

4.对象映射

函数objToMap(obj){

设map=new Map()

For(使用Object.keys(obj)的密钥){

Map.set(key,obj [key])

}

返回地图

}

objToMap({'name':'An','des':'JS'})//Map {'name'=>'An','des'=>'JS'}

5.Map to JSON

函数mapToJson(map){

返回JSON.stringify([. map])

}

设map=new Map()。set('name','An')。set('des','JS')

mapToJson(地图)//[[ '名称', '一个'],[ 'DES', 'JS']]

6.JSON to Map

函数jsonToStrMap(jsonStr){

返回objToMap(JSON.parse(jsonStr));

}

jsonToStrMap('{'name':'An','des':'JS'}')//Map {'name'=>'An','des'=>'JS'}

WeakMap对象是键值对的集合,其中键是弱引用对象,值可以是任意的。

请注意,WeakMap仅弱引用键名,而不是键值。键值仍然是正常参考。

在WeakMap中,每个键对它引用的对象的引用都是弱引用。如果没有其他引用并且该键引用同一个对象,则该对象将被垃圾收集(相应的键变为无效),因此WeakMap该键不可枚举。

属性:

构造函数:构造函数

方法:

Has(key):确定是否存在关键对象get(key):返回键关联对象(无undefined)set(key):设置一组关键对象delete(key):删除关联对象关键

设myElement=document.getElementById('logo');

设myWeakmap=new WeakMap();

myWeakmap.set(myElement,{timesClicked: 0});

myElement.addEventListener('click',function(){

设logoData=myWeakmap.get(myElement);

logoData.timesClicked ++;

},false);

Set成员是唯一的,无序的,不重复[value,value]。键值与键名称(或仅键值,无键名称)相同。方法是:add,delete,hasWeakSet成员都是对象成员。它们都是弱引用,可以通过垃圾收集机制进行回收。它们可用于保存DOM节点。不容易导致遍历内存泄漏。方法包括add,delete和hasMap本质上是键值对的集合。可以遍历类似的集合。可以使用各种数据格式进行转换WeakMap只接受对象作为键名(除了null),不接受其他类型的值作为键名。键名是弱引用,键值可以是任意的,键名指向的对象可以是垃圾回收。此时,密钥名称无效,无法遍历。方法是get,set,has,delete