1、Map
我们知道,在JS中其实对象的方式就跟Java中的Map极为相似,即键值对的方式。JS中,key必须是字符串,实际上Number等值作为key也是合理的,所以为了解决这个问题,在最新的ES6规范中加入了新的数据类型 Map 。
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]);
m.get('Michael'); // 952
1
var m = new Map([['Michael', 95], ['Bob', 75], ['Tracy', 85]]); 2
m.get('Michael'); // 95Map类似二维数组,且每个元素数组的长度为2,其中索引0作为键key,索引1作为值value。所以初始化Map需要一个二维数组,或者直接初始化一个空Map。(常用方法:get获取、set存储、delete删除、has判断包含)
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'); // undefined7
1
var m = new Map(); // 空Map2
m.set('Adam', 67); // 添加新的key-value3
m.set('Bob', 59);4
m.has('Adam'); // 是否存在key 'Adam' --> true5
m.get('Adam'); // 676
m.delete('Adam'); // 删除key 'Adam'7
m.get('Adam'); // undefined同样,作为Map,如果多次对同一个key设置不同的value,之前的值会被替换掉。
2、Set
Set和Map类似也是一组key的集合,但是不存储value,且key不能重复。
创建一个Set,需要提供一个Array作为输入,或者直接创建一个空Set:
var s1 = new Set(); // 空Set
var s2 = new Set([1, 2, 3]); // 含1, 2, 32
1
var s1 = new Set(); // 空Set2
var s2 = new Set([1, 2, 3]); // 含1, 2, 3重复元素在Set中自动被过滤:
var s = new Set([1, 2, 3, 3, '3']);
s; // Set {1, 2, 3, "3"} --> 注意数字3和字符串'3'是不同的元素2
1
var s = new Set([1, 2, 3, 3, '3']);2
s; // Set {1, 2, 3, "3"} --> 注意数字3和字符串'3'是不同的元素通过add(key)方法可以添加元素到Set中,可以重复添加,但不会有效果;通过delete(key)方法可以删除元素。
可以利用这个特性对数组进行去重:
'use strict';
// var set = new Set([1,2,1,2,2,1]);
var arr = [1,2,1,2,2,1];
//new Set 数组去重
function unique(arr){
return Array.from(new Set(arr));
};
//使用ES6的方法可以去重.
console.log(unique(arr));x
1
'use strict';2
// var set = new Set([1,2,1,2,2,1]);3
4
var arr = [1,2,1,2,2,1];5
6
//new Set 数组去重7
function unique(arr){8
return Array.from(new Set(arr));9
};10
//使用ES6的方法可以去重.11
console.log(unique(arr));3、iterable
Array可以通过下标循环遍历,但是Map和Set则无法,所以ES6标准引入了新的iterable类型,Array、Map、Set都属于iterable类型。
回顾:对象可以通过 for in 的方式遍历对象所有属性,虽然说实际上Array也是一个对象,但是用 for in 遍历数组会出现问题,具体的可以戳这里,Array数组实际上也是一个对象,它的每个元素的索引被视为一个属性。当我们手动给Array对象添加了额外的属性后,for ... in循环将带来意想不到的意外效果。
所以对于数组,我们还是尽量避免用 for in 的方式,要么老老实实用 for(var i = 0; i < arr.length; i++) 的方式,要么接着往下看:
具有iterable类型的集合,可以通过 for ... of 循环来遍历,直接遍历其元素,而不单纯是索引:
'use strict';
var a = [1, 2, 3];
for (var x of a) {
alert(x);
}5
1
'use strict';2
var a = [1, 2, 3];3
for (var x of a) {4
alert(x);5
}遍历集合用法如下
var a = ['A', 'B', 'C'];
var s = new Set(['A', 'B', 'C']);
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);
for (var x of a) { // 遍历Array
alert(x);
}
for (var x of s) { // 遍历Set
alert(x);
}
for (var x of m) { // 遍历Map
alert(x[0] + '=' + x[1]);
}12
1
var a = ['A', 'B', 'C'];2
var s = new Set(['A', 'B', 'C']);3
var m = new Map([[1, 'x'], [2, 'y'], [3, 'z']]);4
for (var x of a) { // 遍历Array5
alert(x);6
}7
for (var x of s) { // 遍历Set8
alert(x);9
}10
for (var x of m) { // 遍历Map11
alert(x[0] + '=' + x[1]);12
}还有更好的方式,直接使用 iterable 内置的 forEach 方法,它接收一个函数,每次迭代会自动回调该函数,以Array为例:
var a = ['A', 'B', 'C'];
a.forEach(function(element, index, array){
//element --> 指向当前元素的值
//index --> 指向当前索引
//array --> 指向Array对象本身
alert("element-->"+element);
alert("index-->"+index);
alert("array-->"+array);
});9
1
var a = ['A', 'B', 'C'];2
a.forEach(function(element, index, array){3
//element --> 指向当前元素的值4
//index --> 指向当前索引5
//array --> 指向Array对象本身6
alert("element-->"+element);7
alert("index-->"+index);8
alert("array-->"+array);9
});这里的element、index、array的命名是不固定的,但是固定位置的含义是如上所示的固定的,有一点点类似Java中的方法重载。试一下下面的代码你就明白了:
//Array
var a = ['A', 'B', 'C'];
a.forEach(function(element, index, array){
//element --> 指向当前元素的值
//index --> 指向当前索引
//array --> 指向Array对象本身
alert(element); //首次输出A
alert(element); //首次输出0
alert(element);
});10
1
//Array2
var a = ['A', 'B', 'C'];3
a.forEach(function(element, index, array){4
//element --> 指向当前元素的值5
//index --> 指向当前索引6
//array --> 指向Array对象本身7
alert(element); //首次输出A8
alert(element); //首次输出09
alert(element);10
});而Map和Set的话:
//Map
var b = new Map([['indexA', 'a'],['indexB', 'b'],['indexC', 'c']]);
b.forEach(function(value, key, map){
//value --> 指向当前元素的值
//key --> 指向当前键
//map --> 指向Map对象本身
alert(value); //首次输出a
alert(key); //首次输出indexA
alert(map);
});10
1
//Map2
var b = new Map([['indexA', 'a'],['indexB', 'b'],['indexC', 'c']]);3
b.forEach(function(value, key, map){4
//value --> 指向当前元素的值5
//key --> 指向当前键6
//map --> 指向Map对象本身7
alert(value); //首次输出a8
alert(key); //首次输出indexA9
alert(map);10
});//Set
var c = new Set(['a', 'b', 'c']);
c.forEach(function(key, key, set){
//key --> 指向当前键
//key --> 指向当前键
//set --> 指向Map对象本身
alert(key); //首次输出a
alert(key); //首次输出a
alert(set);
});1
//Set2
var c = new Set(['a', 'b', 'c']);3
c.forEach(function(key, key, set){4
//key --> 指向当前键5
//key --> 指向当前键6
//set --> 指向Map对象本身7
alert(key); //首次输出a8
alert(key); //首次输出a9
alert(set);10
});ES6中迭代器部分,更多可以参考:[译]JavaScript ES6迭代器指南