总结Symbol、Set、WeakSet、Map、WeakMap

发布时间:2024年01月23日

前言

? ? ? ? 这几个es6+新增的数据结构和变量类型,不经常用,好容易忘记啊。在此记录一下,方便复习。

Symbol

? ? ? ? Symbol是es6新增的基本数据类型,用于生成独一无二的值。

? 基本使用

1、创建两个描述相同的值,也不会相等。

let s1 = Symbol(1)
let s2 = Symbol(1)
s1 !==s2 //true

2、s1.description获得描述

let s1= Symbol(‘描述’) 
s1.description//‘描述’ 
//描述可以是字符串或数字,最终都会转为字符串

3、用做对象的属性

  • 添加Symbol属性,需要使用方括号
let sym = Symbol(11);
let o = {};
o[sym] = 11;
//不能在字面量对象中直接添加Symbol属性
/*
{
    Symbol(11):11 //这样会报错
    [sym] : 11 //这样就不会报错
 }
*/

  • 因为Symbol会生成独一无二的值,所以用相同描述创建两个Symbol变量后,就可以添加到对象上,还不会覆盖掉。
let obj = {age:18}
let s1 = Symbol(JSON.stringify(obj))
let s2 = Symbol(JSON.stringify(obj))

//测试开始
let showObj={}
showObj[s1] = 1
showObj[s2] = 2

console.log(showObj)

/*
    {
        Symbol({"age":18}): 1
        Symbol({"age":18}): 2
    }

*/

  • 对象的Symbol属性用Object.keys()等遍历不到,需要使用Object.getOwnPropertySymbols()
Object.getOwnPropertySymbols( obj )//这是单独获取对象自身上的Symbol键的名

4、Symbol.key('描述') 使 “相同描述的Symbol变量”相等

const s1 = Symbol.for(1)
const s2 = Symbol.for(1)
console.log(s1 === s2)//true
console.log(Symbol.keyFor(s1)) //1

可以通过Symbol.keyFor()和description拿到描述。

新增的数据结构

Set

类似数组,但是元素不能重复。(重复的话是删除后面的元素)

创建

//方式1
let set1 = new Set([2,3,4,4,4]) //会去除重复的4

//方式2
let set2 = new Set()
s2.add(2)
s2.add(3)
s2.add(4)

Set变量是类数组,转为真正的数组可以借助Array.from()或[...s1]?

常用方法与属性

1、添加元素
s1.add(元素)
2、删除指定元素,不支持索引
s1.delete(元素)
3、清空整个set
s1.clear()
4、遍历

能用forEach和forof遍历,forin遍历无效。

let set = new Set(['a','b','c']);
set.forEach((value,index) => {
	console.log(value,index); //value等于index
});

5、判断是否包含这个元素
s1.has(元素)

6、s1.size得到set长度

let s1 = new Set([1,2,3])
s1.size //3

WeakSet

WeakSet与Set区别

  • WeakSet只能存放引用类型(object、array、function)的元素,不能存放基本数据类型(number、string、Boolean、undefinend、null、Symbol、BigInt);

  • WeakSet对元素的引用是弱引用,即当其元素没有其他引用指向他时随时会被垃圾回收(WeakSet对其元素的引用不进行计数)

  • weakSet不能清空和遍历,因为弱引用。

WeakSet的应用

一个类的方法只允许new出来的对象进行调用,而不允许显示绑定的this去调用。?

const weakSet1 = new WeakSet()
class Person{
    constructor(){
        weakSet1.add(this)//在new时将this放入WeakSet中存储起来
    }
    eating(){
        if(weakSet1.has(this)){//在实例方法中判断调用该方法时this是否在new的对象中。
            //要執行的邏輯
        }
    }
}

因为WeakSet对其变量是弱引用,Person实例没在其他地方使用时,WeakSet变量就会被回收掉。

Map

存储映射关系,类似二维数组。

创建

在new Map时传入二维数组,对于相同的key,后者覆盖前者。

可以通过set方法添加映射关系。

m1.set({name:'sa'},'值')	//	尾插元素

常用方法与属性

1、m1.get(key) 获取key对应的值

2、m1.has(key) 判断有无key

3、m1.delete(key) 删除key的映射

4、m1.clear() 清空m1

let obj = {age:18}
let m1 = new Map([[obj,18],['name','xiaomi']])
m1.get(obj)	//	获取key对应的值。18

m1.has(obj)	//判断这个key是否在m1 Map中

m1.delete(obj) //删除key的映射

m1.clear() //清空

遍历

用forEach或者forof,同样forin无效。

WeakMap

Map和WeakMap区别

  • weakmap只能用引用类型变量作为key【属性名】

  • weakmap对键是弱引用对值是强引用。(所以适合用对象作为键的情况)

  • 弱引用,所以不能遍历。也没有size和clear()

WeakMap的应用

1、存储缓存结果,而不用担心内存泄漏?。(深拷贝中存储之前的结果用以解决循环引用的问题)

let cache = new WeakMap();

function compute(obj) {
  if (cache.has(obj)) {
    return cache.get(obj);
  } else {
    let result = /* 基于obj计算出一个结果 */;
    cache.set(obj, result);
    return result;
  }
}

2、存储dom节点的元数据,而不用担心内存泄漏

const m1= new WeakMap();
const el= document.getElementById('id');
m1.set(el, '元数据');
m1.get(el) //domx消失,存储的数据也消失

?

END

?????????WeakMap和WeakSet可以解决某些内存泄漏的问题。

????????Map有get和set方法,而Set直接存值,并且没有索引,所以没有get方法,只有add方法(set有需要可以转数组后使用)。

文章来源:https://blog.csdn.net/badbaby52906/article/details/135262426
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。