好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ES6+ 数据结构扩展

ES6+ 数据结构扩展@H_ 419 _2@

1. 前言

编程语言都具有内建的数据结构,但各种编程语言的数据结构常有不同之处。本文将要说的数据结构就是 JavaScript 内建的数据结构及其 属性 。

我们知道在 JavaScript 中有两种数据类型,一种是基本数据类型,另一种是引用类型。ES5 在数据存储时一般使用 Array 或 Object 来存储数据。然而,在越来越复杂的业务中数组和对象已经不能满足我们对数据的存储要求了。ES6 新增了两个用于储存的数据结构 ——Set 和 Map,极大地丰富了 JS 数据存储的能力。

2. Set 数据结构

ES5 中 JavaScript 中没有所谓的集合概念,但是在其他一些语言如:C++、Java、python 等很早就有集合的概念了。ES6 对集合的数据结构进行了补充,引入了 Set 数据结构。

Set 对象允许你存储任何类型的值,且存储的值是唯一的,存储的值可以是原始类型或者是引用类型。并且 Set 对象提供了读、写、查找和遍历等 方法 ,用以更加灵活地操作数据。

Set 是 一个 构造 函数 ,在使用时必须要使用 new 来创建 一个 实例,创建的实例基本上可以当作数组来使用。构造 方法 如下:

  var   set   =   new   Set  (  [ i tera ble ]  )  ; 
 

在 new Set() 时,可以接收 一个 默 认值作为参数,这个参数需要满足 可迭代 的要求。

下面我们看下 方法 的使用实例:

  // 创建 一个 空的 Set 实例 
 var   set   =   new   Set  (  )   // Set(0) {} 
 //  添加 数据 
 set  .  add  (  'es6'  )   // Set(1) {"es6"} 
 // 还可以链式 添加 数据 
 set  .  add  (  'imooc'  )  .  add  (  '7'  )   // Set(3) {"es6", "imooc", "7"} 
 // 接受 一个 可遍历的对象,作为 默 认值,大部分情况是数组 
 var    set    =    new   Set  (  [  ,   ,   ]  ) 
console .  log  (  set  )   // Set(3) {1, 2, 3} 
 

上面的实例就是使用 Set 操作数据的过程,和数字不同的是对于数据的增删改查 Set 都有对应的 方法 ,而数字则通过索引的方式来实现的,这样在一定情况下会出现不可控的因素。后面的章节我们会对 Set 做详细的学习。

3. Map

我们都知道 Object 对象的键只能是基本类型,大部分情况都是字符串,并且 Object 存储的数据是无序的,不能记住插入的先后顺序。

ES6 为了弥补 Object 的缺陷,新增了 Map 数据结构用于存储复杂的数据类型。Map 保存的是键值对,并且能够记住键的插入顺序,而且任何值都可以作为 Map 的键来使用, 包括 引用类型。

和 Set 一样, Map 也是 一个 构造 函数 ,需要通过 new 的方式来创建 一个 Map 实例。

  var  map  =   Map  (  [ i tera ble ]  )  ; 
 

在创建 Map 实例时可以接收 一个 特定的二维数组或是 一个 可遍历的对象作为参数,这个参数内的每一项是以键和值的方式来组合的,如: [key, value] 形式,第 一个 元素键,第二个元素是值。

  // 创建 一个 空的 Map 对象 
 var  map1  =   new   Map  (  ) 
map1 .  set  (  'a'  ,   )  ; 
map1 .  set  (  'b'  ,   )  ; 
map1 .  set  (  'c'  ,   )  ; 
console .  log  ( map1 )   // Map(3) {"a" => 1, "b" => 2, "c" => 3} 

 // map也可以进行链式 调用  
 var  map2  =   new   Map  (  ) 
map2 .  set  (  'a'  ,   )  .  set  (  'b'  ,   )  .  set  (  'c'  ,   ) 
console .  log  ( map2 )   // Map(3) {"a" => 1, "b" => 2, "c" => 3} 

 // 接收 一个 二维数组,二维数组中包含两个值,key和value 
 var   map3   =    new   Map  (  [  [  "x"  ,   ]  ,   [  "y"  ,   ]  ,   [  "z"  ,   ]  ]  )  ; 
console .  log  ( map3 )   // Map(3) {"x" => 10, "y" => 20, "z" => 30} 
console .  log  ( map1 .  get  (  'a'  )  )   // 1 
console .  log  ( map3 .  get  (  'z'  )  )   // 30 
 

上面的 代码 展示了 Map 数据结构 添加 和 获取 操作,和 Set 一样, Map 操作数据也是通过 函数 的方式来实现的。后面的章节我们会对 Map 做详细的学习

4. 数据转换

上面说到的 Set 和 Map 数据结构的简单使用,它们还可以和数组和对象进行对应的转换。这对于数据的操作是非常友好的。下面我们来看下 Set、Map 和 Array、Object 是如何进行转化的。

4.1 Set 转 Array

使用扩展运算符( ... )可以将 Set 数据结构转化数组形式:

  var   set   =   new   Set  (  [  ,   ,   ,   ]  )  ; 
 var  a  =   [  ...  set  ] 
console .  log  ( a )   // [1,2,3,4] 
 

还可以是 ES6 中数组提供的 Array.from() 进行转化。

  var   set   =   new   Set  (  [  ,   ,   ,   ]  )  ; 
Array .  from  (  set  )   // 输出 [1,2,3,4] 
 

4.2 Array 转 Map

上文中学习了将 一个 带键值对的二维数组传入 Map 构造 函数 ,就可以得到 一个 Map 数据结构,这样就可以实现数组转为 Map。

  var  map  =   new   Map  (  [  [  'name'  ,   'imooc'  ]  ,   [  { name :   'imooc'  }  ,   [  'JavaScript'  ,   'ES6 wiki'  ]  ]  ]  )  ; 
 

上面 代码 打印后的结果如下图,引用类型也可以作为 Map 的键保存。

4.3 Map 转 Array

上面我们看到了二维数组转为 Map 数据结构,那么 Map 数据结构怎么转回数组呢?其实很简单,和前面已经提过的 Set 转数组的方式一样,Map 也可以使用扩展运算符 (…) 进行转换。

  const  map  =   new   Map  (  ) 
map .  set  (  'name'  ,   'imooc'  ) 
map .  set  (  { name :   'imooc'  }  ,   [  'JavaScript'  ,   'ES6 wiki'  ]  )  ; 
 [  ... myMap ] 
 // [['name', 'imooc'], [{name: 'imooc'}, ['JavaScript', 'ES6 wiki']]] 
 

4.4 Object 转 Map

Object 转 Map 没有一步到位的 方法 ,需要去遍历 Object 然后逐个 添加 。

  function   objToMap  ( obj )  { 
	 let  map  =   new   Map  (  )  ; 
	 for   (  let   [ key ,  value ]   of  Object .  entries  ( obj )  )  { 
		map .  set  ( key ,  value )  ; 
	 } 
	 return   map ; 
 } 
 objToMap  (  { name :  'imooc'  ,  lesson :   'ES6 Wiki'  }  ) 
 // Map(2) {"name" => "imooc", "lesson" => "ES6 Wiki"} 
 

上面的 代码 中,我们创建了 一个 方法 用于 Object 转 Map 使用, 函数 内部先构造 一个 Map 实例,然后对 Object 进行遍历,逐个 添加 到 Map 实例上。

4.5 Map 转 Object

在 Map 转 Object 时需要注意的是,因为 Map 实例上的键可以是任意类型,而 Object 上的键只能是字符串类型。所有,如果 Map 的键都是字符串,它可以转为对象,如果键是 一个 对象,在转为对象时会被进行 toString 操作。

  function   mapToObj  ( map )  { 
	 const  obj  =   {  } 
	 for   (  let   [ key ,  value ]   of  map )  { 
		obj [ key ]   =  value ; 
	 } 
	 return  obj ; 
 } 
 const  map1  =   new   Map  (  ) 
map1 .  set  (  'name'  ,   'imooc'  ) 
map1 .  set  (  'lesson'  ,   'ES6 Wiki'  )  ; 
 mapToObj  ( map1 )   // {name: "imooc", lesson: "ES6 Wiki"} 

 const  map2  =   new   Map  (  ) 
map2 .  set  (  'name'  ,   'imooc'  ) 
map2 .  set  (  { name :   'lesson'  }  ,   [  'JavaScript'  ,   'ES6 wiki'  ]  )  ; 
 mapToObj  ( map2 )   // {name: "lesson", [object Object]: ["JavaScript", "ES6 wiki"]} 
 

上面的 代码 中需要注意的是 map2,它的第二个元素的键是 一个 对象,在转换对象的键时进行了 toString 操作,变成字符串 [object Object] 。

5. 小结

本节主要学习了 ES6 新增的数据结构 Set 和 Map 的基本使用,并介绍了 Set 和 Map 与 Array 和 Object 之 间的 转化 方法 。从上面的学习中我们知道,ES6 新增 Set 和 Map 这两个数据结构,在弥补 JavaScript 数据结构的同时并规范了操作数据的 方法 。让 JavaScript 更加像一门成熟的语言前进。接下来的几个小节我们会对 Set 和 Map 进行详细的介绍。

查看更多关于ES6+ 数据结构扩展的详细内容...

  阅读:44次

上一篇

下一篇

第1节:ES6+ 简介    第2节:ES6 环境配置    第3节:ES6+ let    第4节:ES6+ const    第5节:ES6+ 展开语法    第6节:ES6+ 剩余参数    第7节:ES6+ 解构赋值    第8节:ES6+ 模版字符串    第9节:ES6+ 箭头函数    第10节:ES6+ 数值扩展    第11节:ES6+ isFinite()&isNaN()    第12节:ES6+ Number 对象的方法    第13节:ES6+ Math 对象的扩展    第14节:ES6+ includes()    第15节:ES6+ 字符串的扩展    第16节:ES6+ startsWith()    第17节:ES6+ endsWith()    第18节:ES6+ repeat()    第19节:ES6+ padStart()    第20节:ES6+ padEnd()    第21节:ES6+ trim()    第22节:ES6+ Array.from()    第23节:ES6+ of()    第24节:ES6+ find()和findIndex()    第25节:ES6+ copyWithin()    第26节:ES6+ fill()    第27节:ES6+ isArray()    第28节:ES6+ 对象的扩展    第29节:ES6+ flat()    第30节:ES6+ 可选链操作符    第31节:ES6+ Object.is()    第32节:ES6+ Object.assign()    第33节:ES6+ Object.keys()    第34节:ES6+ Object.values()    第35节:ES6+ Object.entries()    第36节:ES6+ 数据结构扩展    第37节:ES6+ Set    第38节:ES6+ WeakSet    第39节:ES6+ Map    第40节:ES6+ WeakMap    第41节:ES6+ Symbol    第42节:ES6+ for...of    第43节:ES6+ 迭代协议    第44节:ES6+ 实现一个简版的 Promise    第45节:ES6+ Promise 基础    第46节:ES6+ Promise 进阶    第47节:ES6+ Generator 基础    第48节:ES6+ Generator 函数应用    第49节:ES6+ async/await    第50节:ES6+ Class 前置知识    第51节:ES6+ Class    第52节:ES6+ Proxy    第53节:ES6+ Reflect(一)    第54节:ES6+ Reflect(二)    第55节:ES6+ 模块化(一)    第56节:ES6+ 模块化(二)    第57节:ES6实战1-实现Vue3 reactive 源码    第58节:ES6实战2-实现 Vue3 effect 源码    第59节:ES6 实战2-封装请求    第60节:ES6+ 实战3-代码整洁之道    第61节:ES6 Map原理分析    第62节:ES6module语法加载importexport    第63节:ES6的循环与可迭代对象示例详解