web前端—前端三剑客之JS-ES6(3):Map、WeakMap

目录

Map

 创建Map结构对象

Map数据结构的属性和方法

 增删改查

遍历

Map与数组之间的转换

Map转为数组

数组转为Map

WeakMap 


JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键(ES6加入了Symbol作为属性名称)

Map

Object对象与Map结构对象

  • Object 结构提供了“字符串—值”的对应;
  • Map 结构提供了“值—值”的对应,Map是“键值对”的数据结构,Map键的”范围不限于字符串,各种类型的值(包括对象)都可以当作键

 创建Map结构对象

new Map()  括号中的参数必须是在一个双数组中以键值对存放的数组对象,如[[key1,value1],[key2,value2],...[keyn,valuen]]

let set = new Set([['及时雨','宋公明'],['玉麒麟','卢俊义']]);

任何具有 Iterator 接口且每个成员都是一个双元素的数组( [[a,b],[c,d] ] )的数据结构都可以当作Map构造函数的参数。这就是说,Set和Map都可以用来生成新的 Map。

        let map = new Map([['2','er'],['3','san']]);
        let set = new Set([['及时雨','宋公明'],['玉麒麟','卢俊义']]);
        let a1 = new Map(map);  
        let a2 = new Map(set);
        console.log(a1);
        console.log(a2);

Map数据结构的属性和方法

 增删改查

  • size属性:返回 Map 结构的成员(一个键值对算一个)总数 
  • set(key, value)方法:设置键名key对应的键值为value,然后返回整个 Map 结构。如果key已经有值,则键值会被更新,否则就新生成该键(如果对同一个键多次赋值,后面的值将覆盖前面的值)。
        let bx = document.getElementById('box');
        let arr2 = { bx: 'obj对象' };
        mp.set(arr2, '盒子对象');   // 使用Map对象的set方法添加数据,Map对象的键可以是obj对象
        mp.set(mp_num, 'map对象');
  • get(key)方法:读取key对应的键值,如果找不到key,返回undefined
        let arr1 = ['one', '一'];
        let mp_num = new Map([arr1]);   // 创建一个有键值对的Map对象
        console.log(mp_num.get('one'));   // 获得Map对象键所对应的键值
  • has(key)方法:返回一个布尔值,表示某个键是否在当前 Map 对象之中。
  • delete(key)方法:删除某个键,返回true。如果删除失败,返回false。
        console.log(mp_num.delete('on'));   // 返回false
        console.log(mp_num.delete('one'));   // 返回true
        console.log(mp_num.get('one'));   // 返回undefined
  • clear()方法:清除所有成员,没有返回值。

遍历

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回所有成员的遍历器
  • forEach():遍历 Map 的所有成员
        let set = new Set([['及时雨', '宋公明'], ['玉麒麟', '卢俊义']]);
        let a2 = new Map(set);

        for (let key of a2.keys()) {   // keys方法遍历键
            console.log(key);
        };
        for (let value of a2.values()) {   // values方法遍历值
            console.log(value);
        };
        for (let [key, value] of a2.entries()) {   // entries()遍历键值对
            console.log(key, value);
        };
        for (let iet of a2.entries()) {   // entries()遍历键值对
            console.log(iet);
        };
        for (let [key, value] of a2) {    // 遍历键值对
            console.log(key, value);
        };
        a2.forEach(function (key, value, a2) {   // forEach方法遍历
            console.log('键名key:' + key, '键值value:' + value);
        });

特别注意:Map 的遍历顺序就是插入顺序

Map的forEach方法

forEach方法还可以接受第二个参数,用来绑定this。 上面代码中,forEach方法的回调函数的this,就指向reporter

Map与数组之间的转换

Map转为数组

使用扩展运算符...

        let c = new Map()
            .set('神算子', '蒋敬')
            .set('神行太保', '戴宗');

        let arr_c = [...c];
        console.log(arr_c);

如果所有 Map 的键都是字符串,它可以无损地转为对象。如果有非字符串的键名,那么这个键名会被转成字符串,再作为对象的键名

扩展运算符(...)

Map结构转为数组结构,比较快速的方法是使用扩展运算符(...),可以根据需求选择对值还是键名或是键值对进行数组转换

 

结合数组的map方法、filter方法,可以实现 Map 的遍历和过滤(Map 本身没有map和filter方法)

数组转为Map

使用创建Map对象的方法将数组转为Map

WeakMap 

WeakMap的专用场合

  • 它的键所对应的对象,可能会在将来消失
  • WeakMap结构有助于防止内存泄漏

WeakMap结构与Map结构异同

相同点:

  • 都是用于生成键值对的集合
  • 四种方法都可用:get()、set()、has()、delete()

不同点:

  • WeakMap只接受对象作为键名(null除外),不接受其他类型的值作为键名;
<body>
    <div id="box1">盒子1</div>
    <div id="box2">盒子2</div>
    <div id="box3">盒子3</div>
    <script>
        let b1 = document.getElementById('box1');
        let b2 = document.getElementById('box2');
        let b3 = document.getElementById('box3');
        let wmp = new WeakMap();
        wmp.set(b1,b1.innerText);
    </script>
</body>
  • WeakMap的键名所指向的对象,不计入垃圾回收机制(不算是引用)
  • 没有遍历操作(即没有keys()、values()和entries()方法),也没有size属性。因为没有办法列出所有键名,某个键名是否存在完全不可预测,跟垃圾回收机制是否运行相关。这一刻可以取到键名,下一刻垃圾回收机制突然运行了,这个键名就没了,为了防止出现不确定性,就统一规定不能取到键名
  • 无法清空,即不支持clear方法

经典应用示例

1、myElement是一个 DOM 节点,每当发生click事件,就更新一下状态。我们将这个状态作为键值放在 WeakMap 里,对应的键名就是myElement。一旦这个 DOM 节点删除,该状态就会自动消失,不存在内存泄漏风险

2、部署私有属性。Countdown类的两个内部属性_counter和_action,是实例的弱引用,所以如果删除实例,它们也就随之消失,不会造成内存泄漏。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值