Es6中Map对象和Set对象的介绍及应用

26021次浏览

前言

今天说一说ES6的Set对象和Map对象。以及这两个对象的应用。目前主流浏览器(chrome32、IE11、Safari7.1以及 Firefox 13以上)都对这2个对象做了基本的支持。因此,和css3一样,es6慢慢走进了前端开发的舞台,未来,我们可以不用再利用Babel对ES6语法进行编译就可以直接支持es6语法了。

Map 对象

Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。

Map方法

var myMap = new Map();
myMap.set("bar", "baz");
myMap.set(1, "foo");

myMap.size;       // 2
myMap.has("bar"); // true

myMap.clear();

myMap.size;       // 0
myMap.has("bar")  // false

使用for..of方法迭代映射

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// 将会显示两个log。一个是"0 = zero"另一个是"1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// 将会显示两个log。 一个是 "0" 另一个是 "1"

for (var value of myMap.values()) {
  console.log(value);
}
// 将会显示两个log。 一个是 "zero" 另一个是 "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// 将会显示两个log。 一个是 "0 = zero" 另一个是 "1 = one"

使用forEach()方法迭代映射

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// 将会显示两个logs。 一个是 "0 = zero" 另一个是 "1 = one"

Set 对象

Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。

Set 对象方法

var mySet = new Set();
mySet.add(1);
mySet.add("foo");

mySet.size;       // 2
mySet.has("foo"); // true

mySet.clear();

mySet.size;       // 0
mySet.has("bar")  // false

迭代Set对象

// 迭代整个set
// 按顺序输出:1, "some text" 
for (let item of mySet) console.log(item);

// 按顺序输出:1, "some text" 
for (let item of mySet.keys()) console.log(item);

// 按顺序输出:1, "some text" 
for (let item of mySet.values()) console.log(item);

// 按顺序输出:1, "some text" 
//(键与值相等)
for (let [key, value] of mySet.entries()) console.log(key);

// 转换Set为Array (with Array comprehensions)
var myArr = [v for (v of mySet)]; // [1, "some text"]
// 替代方案(with Array.from)
var myArr = Array.from(mySet); // [1, "some text"]

// 如果在HTML文档中工作,也可以:
mySet.add(document.body);
mySet.has(document.querySelector("body")); // true

// Set和Array互换
mySet2 = new Set([1,2,3,4]);
mySet2.size; // 4
[...mySet2]; // [1,2,3,4]

// 用forEach迭代
mySet.forEach(function(value) {
  console.log(value);
});

Set 与 Array 的联系

var myArray = ["value1", "value2", "value3"];

// 用Set构造器将Array转换为Set
var mySet = new Set(myArray);

mySet.has("value1"); // returns true

// 用...(展开操作符)操作符将Set转换为Array
console.log([...mySet]); // 与myArray完全一致

...扩展语句

扩展语法允许一个表达式在期望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展。

let arr1 = [0, 1, 2];
let arr2 = [3, 4, 5];

arr1 = [...arr2, ...arr1]; 

console.log(arr1) // [3, 4, 5, 0, 1, 2]

应用一:Set对象数组去重

var arr=[3, 62, 3, 38, 20, 42, 14, 5, 38, 29, 42];
console.log(new Set(arr))

可以封装一个函数

function uniqueArray(arr){
    return Array.from(new Set(arr));
}

用这个函数可以数组去重。

或者如下写也可以,比较简单的数组去重

[...new Set([1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0])]

重复值处理

场景:

enter image description here

当地图往下拖的时候要更新地图上的房源标签数据,上图绿框表示不变的标签,而黄框表示新加的房源。

—后端每次都会把当前地图可见区域的房源返回给我,当用户拖动的时候需要知道哪些是原先已经有的房源,哪些是新加的。把新加的房源画上,而把超出区域的房源删掉,已有的房源保持不动。因此需要对比当前房源和新的结果哪些是重复的。因为如果不这样做的话,改成每次都是全部删掉再重新画,已有的房源标签就会闪一下。因此为了避免闪动做一个增量更新。

把这个问题抽象一下就变成:—给两个数组,需要找出第一个数组里面的重复值和非重复值。即有一个数组保存上一次状态的房源,而另一个数组是当前状态的新房源数据。找到的重复值是需要保留,找到非重复值是要删掉的。

用es6 Set对象实现如下:

var lastHouses = new Set();
function filterHouse(houses){
    var remainsHouses = [],
        newHouses = []; 
    houses.map(house => lastHouses.has(house.id) ? remainsHouses.push(house) 
                        : newHouses.push(house));
    newHouses.map(house => lastHouses.add(house.id));
    return {remainsHouses, newHouses};
}

用es6 Map对象实现如下:

var lastHouses = new Map();
function filterHouse(houses){
    var remainsHouses = [],
        newHouses = [];
    houses.map(house => lastHouses.has(house.id) ? remainsHouses.push(house)
            : newHouses.push(house));
    newHouses.map(house => lastHouses.set(house.id, house));
    return {remainsHouses, newHouses};
}

Tags: jsEs6对象MapSet

相关文章: