很多东西就是要细细的品读然后做点读书笔记,心理才会踏实…

Javascript对象本质上就是键值对的集合(Hash结构),但是键只能是字符串,这有一定的限制。

  1. 1
    2
    3
    4
  1. var d = {}
    var ele = document.body
    d[ele] = 'This is body'
    console.log(d['[object HTMLBodyElement]'])

上段代码的原意是将DOM节点作为对象d的键,由于对象只接受字符串,所以ele被自动转为[object HTMLBodyElement]

为了解决这种限制,ES6提供了Map数据结构,类似于对象,但是键的范围不限制于字符串,各类数据类型(包括对象)都可以作为键。

Map基本用法

请看代码

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
  1. var m = new Map()
    m.set('hello', 'Hello guys').set(true, 'right').set({a: 1}, {a: 1})
  2.  
  3. m.size
  4.  
  5. m.get('hello')
    m.has(true)
    m.delete(true)
    m.has(true)

演示过程如下

Map构造函数可以接收数组作为参数,该数组的成员是一个个表示键值对的数组,如

  1. 1
    2
    3
    4
  1. var arr = [ ['name', 'liujiangbei'], ['title', '屌丝男'] ]
  2.  
  3. var map = new Map(arr)
    console.log(map) // Map { 'name' => 'liujiangbei', 'title' => '屌丝男' }

该过程就好比

  1. 1
    2
    3
  1. var map = new Map()
    var arr = [ ['name', 'liujiangbei'], ['title', '屌丝男'] ]
    arr.forEach(([key, value]) => map.set(key, value))

另外需要特别注意,只有对同一个对象的引用,Map结构才将其视为同一个key。一定是内存地址是一样的两个值。

对同一个key进行set,后面的值会覆盖前边的值。

  1. 1
    2
    3
    4
    5
  1. var m = new Map()
    m.set('123', '123')
    m.set('123', '3456')
    m.get('123')
    // 返回 3456

Map的键实际上跟内存地址绑定,只要内存不一样,就视为两个key,这就解决了同名属性碰撞的问题,

如果Map的键是简单类型(数字、字符串、布尔),则只要两个值严格相等,Map就将其视为同一个Key,虽然NaN === NaN为FALSE,但Map将其视为同一Key

  1. 1
    2
    3
    4
    5
    6
  1. let map = new Map()
    map.set(NaN, 123)
    map.get(NaN) // 123
  2.  
  3. map.set(-0, 'Zero')
    map.get(+0) // Zero

这个地方也要特别注意…

Map实例属性和方法

属性和方法

  1. size属性
  2. set(k, v)
  3. get(k)
  4. has(k)
  5. delete(k)
  6. clear()

遍历方法

  1. keys()
  2. values()
  3. entries()
  4. forEach()
  1. 1
  1. for (let [k, v] of map.entries) { console.log(k, v) }

等同于

  1. 1
  1. for (let [k, v] of map) { console.log(k, v) }

因为表示Map结构的默认遍历器结构(Symbol.iterator)就是entries方法

  1. 1
    2
  1. var map = new Map()
    console.log(map[Symbol.iterator] === map.entries)

forEach()方法

  1. 1
    2
    3
    4
    5
  1. var obj = {}
    map.forEach(function (key, value, map) {
    // do somethings
    // this 指向 obj 对象
    }, obj)

Map和Array等数据结构的化学反应

Map和Array

前边讲到Map的构造函数接收数组,所以Map和Array之间的转化比较方便,但是也有一些约束。

大专栏  ES6中Map数据结构学习笔记ap">Array转Map

  1. 1
    2
    3
  1. var arr = [[1, 'ext', '1'], ['2', 2], [3, '3', 'ext']]
    var map = new Map(arr)
    console.log(map)

可以看出数组转为Map需要满足,数组的元素为数组或者object。

Map转Array

利用扩展运算符...很容易实现

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
  1. var arr = [
    ['1', '111'],
    [2, [122, 122]],
    ['name', 'liujiangbei']
    ]
    var map = new Map(arr)
  2.  
  3. var keys = [...map.keys()]
    var values = [...map.values()]
    var entries = [...map.entries()]
    entries === [...map] // false


利用Array的map和filter方法实现Map的map和filter特性

Map本身并没有map和filter方法,由于数组和Map转换很方便所以利用数组的map的filter特性从而实现达到map和filter的特性。

  1. 1
    2
    3
    4
    5
  1. var arr = [[1, '1'], [2, '222'], [3, '333']]
    var map = new Map(arr)
  2.  
  3. new Map([...map].filter(([k, v]) => k >= 1))
    new Map([...map].map( ([k, v]) => [k * 2, `Map_${v}`] ))


Map和Object

Map转为Object

如果Map的键全为字符串、数字、bool,则其可以转为对象,键非字符串的会通过.toString()方法转化。

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
  1. function mapToObj (map) {
    var obj = Object.create(null)
    for (let [k, v] of map) {
    obj[k] = v
    }
    return obj
    }
  2.  
  3. var map = new Map( [[1, '1'], [true, true], ['111', '111'], [{1: 1}, 111] ])
    var obj = mapToObj(map)
    console.log(obj)
    console.log(typeof obj.true, obj.true)

Object转为Map

  1. 1
    2
    3
    4
    5
    6
    7
    8
    9
  1. function objToMap (obj) {
    let map = new Map()
    for (let k of Object.keys(obj)) {
    map.set(k, obj[k])
    }
    return map
    }
  2.  
  3. objToMap({yes: true, no: false, 1: 11})

Map和JSON

Map转为JSON

Map的键都是字符串,这是直接转为对象JSON

  1. 1
  1. JSON.stringify(mapToObj(obj))

Map的键有非字符串,这是可选择转为数组JSON

  1. 1
  1. JSON.stringify([...map])

JSON转Map

JSON都是字符串的方式,所以先通过JSON.parse(jsonStr)转为对象,然后通过上边的objToMap即可实现转化

有一种特殊情况,整个JSON就是一个数组,诶个数组成员又都是有两个成员的数组,他可以一一对应转为Map

  1. 1
  1. new Map(JSON.parse(jsonStr))

结束语

网络上这么多同类型的文章为何我还要多此一举?
看到的永远是别人的,写下来才是自己的,知易行难,日拱一卒,坚持比什么都重要!这句话送给大家也送给我自己…

ES6中Map数据结构学习笔记的更多相关文章

  1. ES6中map数据结构学习

    在项目中遇到一个很恶心的需求,然后发现ES6中的map可以解决,所以简单学习了一下map. Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是“字符串-值”对,属性只 ...

  2. JavaSE中Map框架学习笔记

    前言:最近几天都在生病,退烧之后身体虚弱.头疼.在床上躺了几天,什么事情都干不了.接下来这段时间,要好好加快进度才好. 前面用了三篇文章的篇幅学习了Collection框架的相关内容,而Map框架相对 ...

  3. ES6-Set和Map数据结构学习笔记

    Set和Map数据结构 Set 基本用法 ES6提供了新的数据结构--Set,类似于数组,但是成员的值是唯一的,没有重复的值,Set本身是一种构造函数,用来生成Set数据结构 var s = new ...

  4. ES6中map数据结构

    key值可以任意值或对象,value值可以是任意值或对象 let json={ name:'eternity', skill:'java' }; let map=new Map(); map.set( ...

  5. ES6中map和set用法

    ES6中map和set用法 --转载自廖雪峰的官方网站 一.map Map是一组键值对的结构,具有极快的查找速度. 举个例子,假设要根据同学的名字查找对应的成绩,如果用Array实现,需要两个Arra ...

  6. C++中的ravalue学习笔记

    一.学习笔记 1. A a = 42; 会先以42为参数构造一个A类对象,然后调用拷贝构造函数来构造a,目前编译器优化掉了拷贝构造函数的调用,测试拷贝构造函数是没有被调用的,但是其权限不能为priva ...

  7. 我的Android进阶之旅------>Android中编解码学习笔记

    编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中媒体的编解码服务涉及需求分析.应用开发.释放license收费等等 ...

  8. ES6基础教程一 学习笔记

    一.变量的声明 1.var 声明全局变量 在ES6中var用来声明全局变量. 2.let 声明局部变量 3.const 声明常量 二.变量的解构赋值 //1.数组赋值 let [a,b,c]=[1,2 ...

  9. ES6中Map与其他数据结构的互相转换

    最近在学习ES6的基础知识,整理了一下Map与其他数据结构相互转换的写法. Map转为数组的方法 let myMap = new Map([[true, 7], [{foo: 3}, ['abc']] ...

随机推荐

  1. 吴裕雄--天生自然 pythonTensorFlow图形数据处理:图像预处理完整样例

    import numpy as np import tensorflow as tf import matplotlib.pyplot as plt #随机调整图片的色彩,定义两种顺序. def di ...

  2. Eclipse Jee 2019-12 使用的一些小窍门(积累性更新)

    在安装使用 Eclipse IDE for Enterprise Java Developers  Version: 2019-12 M1 (4.14.0) 之前请确保已在系统环境变量配置好JDK1. ...

  3. spark mllib lda 中文分词、主题聚合基本样例

    github https://github.com/cclient/spark-lda-example spark mllib lda example 官方示例较为精简 在官方lda示例的基础上,给合 ...

  4. Java源码之ArrayList

    本文源码均来自Java 8 总体介绍 Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类.Set和List两个类继承于它.Set中不能包含重复的元素,也没有顺序来存放. ...

  5. OneDrive for Business

    一.界面介绍 1.在Office 365主页 点击“OneDrive”登陆 2.进入OneDrive,可对文档进行存储.同步并共享文档. 3.点击,可对文档进行编辑.分享.重命名等操作 二.文档同步 ...

  6. MOOC(15)- 接口异常处理

    首先通过fiddler拿到正确的传参 把value复制下来,存到json数据中,传参时通过键去json的值即可 但是运行请求的时候报错了 再运行,还是出错 查看fiddler结果 修改,从fiddle ...

  7. Qt QString的arg()方法的使用

    1.QString的arg()方法用于填充字符串中的%1,%2...为给定的参数,如 QString m = tr("); // m = "12:60:60: 2.它还有另外一种重 ...

  8. RabbitMQ传输原理、五种模式

    本文代码基于SpringBoot,文末有代码连接 .首先是一些在Spring Boot的一些配置和概念,然后跟随代码看下五种模式 MQ两种消息传输方式,点对点(代码中的简单传递模式),发布/订阅(代码 ...

  9. 关于虚拟机VMware Tools安装中出现的无法自动安装VMCI驱动程序的问题

    问题 解决方法 根据配置文件信息找到所在的虚拟机位置 找到后缀名为vmx的文件,右键打开方式中选择使用记事本打开 选择左上角编辑中的查找功能输入图中的查找内容后,点击查找下一个 将其原先的TRUE值改 ...

  10. 从源码看commit和commitAllowingStateLoss方法区别

    Fragment介绍 在很久以前,也就是我刚开始写Android时(大约在2012年的冬天--),那时候如果要实现像下面微信一样的Tab切换页面,需要继承TabActivity,然后使用TabHost ...