《深入理解ES6》第七章 Set 与 Map

第七章 Set 与 Map

《深入理解ES6》—— Nicholas C. Zakas

ES6之前 JS只存在一种集合类型,就是数组类型。

数组只使用了数值型的索引,
而如果非数值型的索引是必要的,开发者就会使用非数组的对象。

这种技巧引入了非数组对象的定制实现,即 Set 与 Map。

Set 是不包含重复值的列表。Map则是键与相对应的值的集合。

1. ES5中的 Set 与 Map

1.1. 用对象模拟

let set = Object.create( null );
let map = Object.create( null );

setmap的原型对象是 null,确保在此对象上没有继承属性。

set 只关注键不重复。
map 关注值。

1.2. 问题

  • key只能是字符串
  • 检查属性的存在性的问题: if ( map.key1 ) { ... }

2. ES6 的 Set

ES6新增了 Set 类型,这是一种无重复值的有序列表。

2.1. 使用

// 创建
let set = new Set();

// 添加项目
set.add( 5 );
set.add( "5" );

// 获取项目总数
set.size; //=> 2

// 用数组初始化
set = new Set( [ 1, 2, 3, 3, 3] );
set.size; //=> 3

// 判断是否存在某值
set.has( 1 ); //=> true
  • Set内部通过 Object.is() 判断是否相等

2.2. 移除值

let set = new Set( [ 5, "5" ] );

// 删除单个值
set.delete( 5 );
set.size; //=> 1

// 清空
set.clear();
set.size; //=> 0

2.3. 遍历

let set = new Set( [ 1, 2] );

// value:值
// key:Set没有key,其值与value一致
// ownerSet:目标 Set
set.forEach( function( value, key, ownerSet ) {
    console.info( value, Object.is( value, key ) );
} );

2.4. 转换为数组

// 可用于去重
let set = new Set( [ 1, 2, 2, 3 ] );
let array = [...set];

array; //=> [ 1, 2, 3 ]

2.5. WeakSet

如果值是对象的引用,但该对象(比如DOM)被移除后:

  • Set 仍旧存储该引用,这会造成内存泄露
  • WeakSet 不会再存储该引用,它只允许存储对象的弱引用

WeakSet 只允许存储对象的引用。

3. ES6 的 Map

ES6的 Map 类型是键值对的有序列表,键的比较使用的是 Object.is()

3.1. 使用

let map = new Map();

// 添加/设置 项目
map.set( "name", "吴钦飞" );
map.set( "gender", "男" );

// 获取项目
map.get( "name" ); //=> "吴钦飞"

3.2. 方法

  • has( key ):判断指定的键是否存在于 Map 中
  • delete( key ):移除 Map 中对应的键及值
  • clear():清空

3.3. 初始化

// 一维数组的每一项为 Map 中的一个键值对
let map = new Map( [
    // 第一个元素为 键,第二个元素为 值
    [ "name", "吴钦飞" ], 
    [ "gender", "男" ]
] );

map.get( "name" ); //=> "吴钦飞"

3.4. 遍历

let map = new Map( [
    [ "name", "吴钦飞" ],
    [ "gender", "男" ]
] );

map.forEach( function( value, key, ownerMap ) {
    console.info( key + " " + value );
} );

3.5. WeakMap

  • 所有键必须是对象,且键都是弱引用
  • 不会干扰垃圾回收,当键在 WeakMap之外不存在引用时,该键值会被移除
  • 适合在浏览器中创建一个关联到特定DOM元素的对象。

某些用在网页上的JS库会维护一个自定义对象,
用于引用该库所使用的每一个DOM元素,
并且其映射关系会存储在内部的对象缓存中。

如何判断一个DOM元素已不复存在于网页中,
以便该库能移除此元素的关联对象。
若做不到,该库就会继续保持对DOM元素的一个无效引用,并造成内存泄露。

私有数据:

let Person = ( function() {
    let privateData = new WeakMap();
    function Person( name ) {
        privateData.set( this, { name: name } );
    }
    Person.prototype.getName = function() {
        return privateData.get( this ).data;
    }
} )();
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值