ES6中Map和Set

前言 ◣

ES6是JavaScript语言的新标准,2015年6月正式发布后,迅速推广, 现在大多数浏览器都支持ES6中的大多数特性.
而本文将对ES6新增数据结构集Map和Set进行了解.

Map ◣

	Map顾名思义,地图本就有 一 一 对应的特点,就像字典一样.
	Map结构是键值的组合,它的key不止限于字符串类型 , key可以为任何类型.[如下所示:]
    var m = new Map();
            
    var key1 = "String";  
    var key2 = {name:'李四'};   
    var key3 = function(){}; 
     
    m.set(key1, "value1"); //key为字符串
    m.set(key2, "value2"); //key为对象
    m.set(key3, "value3"); //key为函数

    console.log(m.get(key1)); //value1
    console.log(m.get(key2)); //value2
    console.log(m.get(key3)); //value3

事实上Map的key是与内存地址绑定的,只要内存地址不一样,就会视为两个键, 所以Map的key可以为任何的数据类型.


Map常用操作方法:

set(key,val): 添加某个值,返回Map结构本身。
get(key)    : 读取某个键,如果该键未知,则返回undefined
delete(key) : 删除某个键,返回一个布尔值,判断是否删除成功。
has(key)    : 返回一个布尔值,判断该值是否为Map的键。
clear()     :  清除所有成员,没有返回值。
属性 size        :  返回映射对象中的键/值对的数目。

遍历:

keys():返回键名的遍历器。
values():返回键值的遍历器。
entries():返回所有成员的遍历器。
forEach():遍历 Map 的所有成员。

还可以使用 for…of

var m = new Map();
 m.set('a', 1);
 m.set('b', 2);
for (var [key,value] of m) {
  console.log(key+":"+value);
}
//输出 a:1 b:2 .

Map对象与其他数据结构转换

1. Map转数组
let m = new Map([['name','王鑫'],['age','21']]);
console.log(...m)
//[['name','王鑫'],['age','21']]
2. 数组转Map
let ar = [['name','王鑫'],['age','21']];
let m = new Map(ar);
//Map(2) {"name" => "王鑫", "age" => "21"}
3. Map转对象
let m = new Map([['name','王鑫'],['age','21']]);

function method(map){
  let obj = Object.create(null); //创建一个空对象
  for(let [key,value] of map){
    obj[key] = value;
  }
  return obj
}
method(person);
//{name: "王鑫", age: "21"}
4. 对象转Map
let obj ={'name':'alan','age':'20'};

function method(ot){
  let m = new Map();
  for(let key of Object.keys(ot)){
    map.set(key,ot[key]);
  }
  return m
}
method(obj);

注意:

如果Map的键是一个基本类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键.。如0和-0:
    var m = new Map(); 
    if(0===-0)
     console.log("true");
    else
     console.log("false");
   //输出 true
    m.set(0,3);
    m.set(-0,4);
    console.log(m.size);   // 1
    console.log(m.get(0)); // 4
    console.log(m.get(-0)) // 4

另外NaN不严格相等于自身,但Map将其视为同一个键。

    var m = new Map(); 
    if(NaN===NaN)
     console.log("true");
    else
     console.log("false");
   //输出 false
    m.set(NaN,3);
    m.set(NaN,4);
    console.log(m.size);      // 1
    console.log(m.get(NaN));  // 4
    console.log(m.get(NaN))   // 4

因为Map的set方法返回的是Map本身,所以可以采用链式写法。

var m = new Map();
m.set('num',1).set(1,"数字");
console.log(m.get(1)) //数字

WeakMap

提到 Map 不得不提到它兄弟 WeakMap
WeakMap 同样是键值对集合 但它的key不能基本数据类型(数值,字符串等), 只能是对象 (不包括null). 方法也只有4个:
set(key, val)
get(key)
has(key)
delete(key)

扫描二维码关注公众号,回复: 10988565 查看本文章

此外它的 key 都是弱引用(这点与Map相反),说人话就是 WeakMap 内的东西垃圾回收时不考虑,使用它不用担心内存泄漏问题。
(内存泄漏:申请的内存空间没有被正确释放,导致后续程序里这块内存被永远占用(不可达),而且指向这块内存空间的指针不再存在时,这块内存也就永远不可达了,内存空间就这么一点点被消耗);


Set ◣

Set数据结构是一个类似于数组,但是与数组不同的是它具有唯一性,里面的元素都是不重复的,值可以是原始类型和引用类型.

Set常用操作方法:

set(key, value) : 设置key所对应的value值
get(key)        : 获取key所对应的value值,若无则undefined
has(key)        :返回一个布尔值,判断该值是否为Map的键。	
delete(key)     : 删除某个键,如删除失败返回false
clear()         : 清除所有成员
属性 size       :  返回的是set实例的长度。

当然Set的用途不止这些,可以利用Set结构特性玩些不一样的操作:

	1.可以用它去除一组数据中重复的值.
let a = new Set([1,2,3,3,4,5,5,6,6,7]);
console.log([...a]);	//[1, 2, 3, 4, 5, 6, 7]
	2.查找两组数据中的交集
let a = new Set([1,2,3]);
let b = new Set([3,4,5]);
//交集
let value = new Set([...a].filter( item => b.has(item)));
console.log([...value]); //[3]]
	3.查找两组数据中的并集
let a = new Set([1,2,3]);
let b = new Set([3,4,5]);
//并集
let value = new Set([...a],[...b]);
console.log([...value]); //[1, 2, 3, 4, 5]
	4.查找两组数据中的差集
let a = new Set([1,2,3]);
let b = new Set([3,4,5]);
//差集
let value = new Set([...a].filter(item=>!b.has(item)));
console.log([...value]); //[1, 2]  这里是b相对于a来说没有的元素
补充 : 
 filter()是Array对象方法之一,
 filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。
语法:
  ..........................................................................
  array.filter(function(currentValue,index,arr), thisValue);
  ..........................................................................
  currentValue | 必须 | 当前元素的值
  index        | 可选 | 当前元素的索引值
  arr          | 可选 | 当前元素属于的数组对象
  thisValue    | 可选 | 对象作为该执行回调时使用,传递给函数,用作 "this" 的值。

如果省略了 thisValue ,“this” 的值为 “undefined”

!!!注意:
    filter() 不会对空数组进行检测。
    filter() 不会改变原始数组。

遍历
Set 结构的实例同样有四个遍历方法,可以用于遍历成员。

keys()   :返回键名的遍历器 
values() :返回键值的遍历器
entries():返回键值对的遍历器
forEach():使用回调函数遍历每个成员
-----------------------------------------------------------------
!!!注意: 由于Set没有键名,只有值名,keys()和values()返回的结果是一样.
-----------------------------------------------------------------

还可以使用 for…of

var s = new Set(1,2,3,4,5,6);
for (let val of s) {
  console.log(val);
 //1 2 3 4 5 6
}

这里需要说下,Set的遍历顺序就是插入的顺序,这个特性某些时候非常有用.


WeakSet

当然Set也有自己的同胞 WeakSet

从字面来看,WeakSet 是一个弱结构,与WeakMap相似,它的值是弱引用,则其引用不计入垃圾回收机制

除了定义不同之外,WeakSet没有size属性,也不可以进行遍历操作,因为它可能随时会被回收,垃圾回收机制执行过后,元素个数可能不一样.

常用操作方法

add()	: 添加新元素
delete(): 删除WeakSet的成员
has()   : 判断WeakSet是否含有某个元素

今天的分享到这就告一段落咯,之后还会继续更新,欢迎大家继续关注。

参考:
ES6 菜鸟教程

发布了2 篇原创文章 · 获赞 3 · 访问量 601

猜你喜欢

转载自blog.csdn.net/AKALXH/article/details/105635226
今日推荐