ES6躬行记(17)——Map

一、Map

  Map类似于Object(对象),可用来存储键值对,但需要通过SameValueZero算法保持键的唯一性。与Set一样,在使用之前也得要实例化,如下代码所示,构造函数Map()中的参数也是一个可选的可迭代对象,但此对象得是键值对的集合或两列的二维数组。

new Map();                                //Map(0) {}
new Map([["name", "strick"], ["age", 28]]);    //Map(2) {"name" => "strick", "age" => 28}

1)属性和方法

  Map比Set多一个读取方法:get(),并且写入方法改成了set(),其它的属性和方法在功能上基本都一致,只是有些参数在含义上略有不同,例如delete()的参数表示键而不是值。方法的具体使用,可参加下面的代码。

var people = new Map();
//写入和读取
people.set("name", "strick").set("age", 28);  //Map(2) {"name" => "strick", "age" => 28}
people.get("name");                 //"strick"
people.size;                     //2
//遍历
[...people.keys()];            //["name", "age"]
[...people.values()];          //["strick", 28]
[...people.entries()];         //[["name", "strick"], ["age", 28]]
/*
  "strick" "name" Map(2) {"name" => "strick", "age" => 28}
  28 "age" Map(2) {"name" => "strick", "age" => 28}
*/
people.forEach(function(value, index, map) {
  console.log(value, index, map);
});
//移除
people.delete("name")
people.has("name");           //false
people.clear();
people.has("age");            //false

2)比较对象

  本节开篇就提到Map和Object很类似,但其实两者之间还是有一些很重要的区别,具体如表10所列。

表10  Map和Object的对比

不同点 Map Object
所有类型,甚至包括NaN 字符串或Symbol类型
可迭代对象
尺寸 通过size属性得到 需要手动计算
原型
写入 set()方法 等号运算符
读取 get()方法 成员访问运算符(点号或方括号)
移除 delete()或clear()方法 delete运算符
枚举顺序 根据键值对的添加顺序 依照ES6的新规则

二、WeakMap

  WeakMap是Map的变体,也是键值对的集合,但它的键必须是弱引用的对象,并且不可枚举,而值没有限制,还是保持任意类型。当WeakMap的键所指的对象不再被引用时,其键和值将被GC自动回收。

1)创建和方法

  WeakSet也需要像Map那样实例化(如下代码所示),但没有Map的size属性,并且只包含Map中的四个方法:set()、get()、has()和delete(),诸如清空和遍历相关的方法都是不存在的。

var weak = new WeakMap(),
  arr = [1];
weak.set(arr, 10);    //WeakMap {Array(1) => 10}
weak.get(arr);        //10
weak.has(arr);        //true
weak.delete(arr);
weak.has(arr);        //false

2)用途

  WeakMap的主要优势在于不干扰垃圾收集,从而能够有效的防止内存泄漏。它适用于隐藏信息、存储DOM节点等场景。下面是一个隐藏信息的示例,privates变量是一个WeakMap,它的键是当前实例化的People对象,存储的私有数据是一个对象,两个原型方法分别用于写入和读取name属性。

var people = (function() {
  var privates = new WeakMap();
  function People() {
    privates.set(this, {});     //初始化私有数据
  }
  People.prototype.setName = function(name) {
    privates.get(this).name = name;        //写入
  };
  People.prototype.getName = function() {
    return privates.get(this).name;        //读取
  };
  return new People();
})();
people.setName("strick");
people.getName();              //"strick"

  这种存储方式不仅能让数据保持私有状态,并且当与之关联的对象实例被销毁后,这些私有数据将被GC一并删除,从而释放内存。

  下面是另一个存储DOM节点的示例,node变量是一个WeakMap,它的键是文档中的<div>元素(即DOM的一个节点),在该元素的事件处理程序中可更新digit属性。当从文档中移除该元素时,与之关联的数据也会随之被删除。

<div id="container"></div>
<script>
    var container = document.getElementById("container");
    var node = new WeakMap();
    node.set(container, { digit: 0 });
    container.addEventListener("click", function() {
        var current = node.get(this);
        current.digit++;
        node.set(this, current);
      },
      false
    );
</script>

 

相关推荐:

Python map filter reduce 区别解析

map、filter、reduce的核心区别是:map一对一转换元素,filter按条件筛选子集,reduce累积计算得单值;三者均不修改原数据,返回惰性对象(reduce除外),体现函数式编程思想。 这三个函数都是Python中处理可迭代对象的高阶函数,核心区别在于:map用于逐个转换元素,fil...

Python 使用 map 与 filter 的现实意义

应优先使用列表推导式而非map和filter,因其更直白、易调试、性能略优;仅在需惰性求值、复用纯函数或流式处理时才考虑map/filter。 map和filter在真实代码里到底该不该用 多数人写map和filter是为了“看起来更函数式”,但实际项目中,它们常让逻辑变难读、调试变困难、性能无优势...

Python 多进程 multiprocessing 里 Pool.map 怎么传复杂参数?

Pool.map仅接受单个可迭代参数,需用functools.partial预绑定固定参数或包装函数解包元组;starmap不支持关键字参数且灵活性低;状态对象需改无状态或换ProcessPoolExecutor。 Pool.map只接受单个可迭代参数,不能直接传多个参数 这是最常踩的坑:Pool....

vue怎么获取map中的值

本篇内容介绍了“vue怎么获取map中的值”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!具体方法如下:1.使用Object方法获取map中的key和value值<template> &lt...

C++利用map实现并查集的方法

这篇文章将为大家详细讲解有关C++利用map实现并查集的方法,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。并查集(Union-Find)是一种树型的数据结构,用于处理一些不相交集合(DisjointSets)的合并及查询问题。并查集存在两个操作(1.Union联合...

详解ES6中的代理模式——Proxy

什么是代理模式 代理模式(英语:ProxyPattern)是程序设计中的一种设计模式。 所谓的代理者是指一个类别可以作为其它东西的接口。代理者可以作任何东西的接口:网络连接、内存中的大对象、文件或其它昂贵或无法复制的资源。 著名的代理模式例子为引用计数(英语:referencecounting)指针...

ES6 Proxy如何在JavaScript中使用

ES6Proxy如何在JavaScript中使用?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。为函数添加特定的功能 * 为异步函数添加自动超时功能  * @param timeout...

vscode es6语法报错怎么办

这篇文章给大家分享的是有关vscodees6语法报错怎么办的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vscodees6语法报错  用VSCode开发ES6语法的项目,Promise等关键字和语法不识别,报错。解决方法:在项目根目录下建两个文件:.e...