ES6 Map Set总结

JavaScript教程传送门

JavaScript的默认对象表示方式{}可以视为其他语言中的MapDictionary数据结构,即一组键值对。

但是javascript的对象有个小问题,就是键必须是字符串。但实际上Number或者其他数据类型作为键也是非常合理的。

为了解决这个问题,最新的ES6规范引入了新的数据类型Map

Map

Map是一组键值对的结构,具有极快的查找速度。

举个例子,假设要根据考试的排名查找对应的同学的名字,如果用Array实现,需要两个Array

var ranks = [1, 2, 3];
var names = ['Michael', 'Bob', 'Tracy'];
  
  
  • 1
  • 2
  • 1
  • 2

给定一个名次,要查找对应的同学名字,就先要在ranks中找到对应的位置,再从names取出对应的成绩,Array越长,耗时越长。

如果用Map实现,只需要一个“名次”-“名字”的对照表,直接根据名次查找同学名字,无论这个表有多大,查找速度都不会变慢。用JavaScript写一个Map如下:

var m = new Map([[1, 'Michael'], [2, 'Bob'], [3, 'Tracy']]);
m.get(1); // 'Michael'
  
  
  • 1
  • 2
  • 1
  • 2

初始化Map需要一个二维数组,或者直接初始化一个空MapMap具有以下方法:

var m = new Map(); // 空Map
m.set('Adam', 67); // 添加新的key-value
m.set('Bob', 59);
m.has('Adam'); // 是否存在key 'Adam': true
m.get('Adam'); // 67
m.delete('Adam'); // 删除key 'Adam'
m.get('Adam'); // undefined
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

由于一个key只能对应一个value,所以,多次对一个key放入value,后面的值会把前面的值冲掉:

var m = new Map();
m.set('Adam', 67);
m.set('Adam', 88);
m.get('Adam'); // 88
  
  
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4
*注意:只有针对同一个对象的引用,Map结构才将其视作同一个键。这一点要非常小心才行。*
var map = new Map();

map.set(['a'], 555);
map.get(['a']);  // undefined
上面代码中set和get方法表面上是针对同一个键,但实际上这是两个值,内存地址是不一样的,因此get方法无法读取该键,返回undefined。 再看看下面一段代码:
var map = new Map();

var k1 = ['a'];
var k2 = ['a'];

map.set(k1, 111);
map.set(k2, 222);

map.get( k1 );  //111
map.get( k2 );  //222

上面代码,变量k1和k2的值是一样的,但是他们在Map结构中被视为两个键。即同样值的两个实例,在Map中被视为两个键。

## 属性和方法 ##

Map结构有以下属性和方法:
- size : 返回成员总数。
- set(key, value) : 设置一个键值对。
- get(key) : 读取一个键。
- has(key) : 返回一个布尔值,表示某个键是否在Map结构中。
- delete(key) : 删除某个键。
- clear() : 清除所有成员。

var m = new Map();

m.set("edition", 6); // 键是字符串
m.set(262, "standard"); // 键是数字
m.set(undefined, "nah"); //键是undefined

var hello = function() {
    console.log("hello");
}
m.set(hello, "Hello ES6!");  //键是函数

m.has("edition");  //true
m.has("years");  //false
m.has(262);  //true
m.has(undefined);  //true
m.has(hello);  //true

m.delete( undefined );  
m.has( undefined );  //false

m.get( hello );  //hello ES6!
m.get("edition");  //6
## 遍历 ##

Map原生提供三个遍历器。

  • key() : 返回键名的遍历器。
  • values() : 返回键值的遍历器。
  • entries() : 返回所有成员的遍历器。
for ( let key of map.key() ) {
    console.log("key: %s", key);
}

for ( let value of map.value() ) {
    console.log("value: %s", value);
}

for ( let item of map.entries() ) {
    console.log("Key: %s, Value: %s", item[0], item[1]);
}

// same as using map.entries()
for (let item of map) {
    console.log("Key: %s, Value: %s", item[0], item[1]);
}
另外,Map还有一个forEach方法,与数组中的forEach方法类似,也可以实现遍历。
map.forEach(function(value, key, map) {
    console.log("Key: %s, Value: %s", key, value);
});
forEach方法还可接受第二个参数,用来绑定this。
var reporter = {
    report: function(key, value) {
        console.log("key: %s, Value: %s", key, value);
    }
};

map.forEach(function(value, key, map) {
    this.report(key, value)
}, reporter);
上面代码中,forEach()方法的回调函数中的this, 就指向reporter。

Set

SetMap类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在Set中,没有重复的key。

要创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set

var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 3
 
 
  • 1
  • 2
  • 1
  • 2

重复元素在Set中自动被过滤:

var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"}
 
 
  • 1
  • 2
  • 1
  • 2

通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果:

var s = new Set([1, 2, 3]);
s.add(4);
s; // Set {1, 2, 3, 4}
s.add(4);
s; // Set {1, 2, 3, 4}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

通过delete(key)方法可以删除元素:

var s = new Set([1, 2, 3]);
s; // Set {1, 2, 3}
s.delete(3);
s; // Set {1, 2}
 
 
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

Set结构有以下属性:

  • Set.prototype.constructor: 构造函数,默认就是Set函数。
  • set.prototype.size : 返回Set的成员总数。

Set结构有以下方法:

  • add(value) : 添加某个值。
  • delete(value) : 删除某个值。
  • has(value) : 返回一个布尔值,表示该值是否为Set的成员。
  • clear() : 清除所有成员。
s.add(1).add(2).add(2); // 注意“2”被加入了两次
s.size //2

s.has(1) // true
s.has(2) // true
s.has(3) // false

s.delete(2);
s.has(2)  // false

下面对比以下,看看在判断是否包括一个键上面,对象和Set的写法有哪些不同。

// 对象写法
var properties = {
    "width": 1,
    "height": 1
};

if ( properties[someName]) {
    // do something
}

/****************************************/

// Set的写法
var properties = new Set();

properties.add('width');
peoperties.add('height');

if ( properties.has(someName) ) {
    // do something
}

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

var items = new Set([1, 2, 3, 4, 5]);
var array = Array.from( items );

这也提供了一种除去数组中重复元素的方法。

function dedupe( array ) {
    return Array.from( new Set(array) );
}
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值