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; //
//遍历
[...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); //
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>
ES6躬行记(17)——Map的更多相关文章
- ES6躬行记(1)——let和const
古语云:“纸上得来终觉浅,绝知此事要躬行”.的确,不管看了多少本书,如果自己不实践,那么就很难领会其中的精髓.自己研读过许多ES6相关的书籍和资料,平时工作中也会用到,但在用到时经常需要上搜索引擎中查 ...
- ES6躬行记 笔记
ES6躬行记(18)--迭代器 要实现以下接口## next() ,return,throw 可以用for-of保证迭代对象的正确性 例如 var str = "向
- ES6躬行记(21)——类的继承
ES6的继承依然是基于原型的继承,但语法更为简洁清晰.通过一个extends关键字,就能描述两个类之间的继承关系(如下代码所示),在此关键字之前的Man是子类(即派生类),而在其之后的People是父 ...
- ES6躬行记(18)——迭代器
ES6将迭代器和生成器内置到语言中,不仅简化了数据处理和集合操作,还弥补了for.while等普通循环的不足,例如难以遍历无穷集合或自定义的树结构等. 迭代器(Iterator)是一种用于迭代的对象, ...
- ES6躬行记(16)——Set
ES6引入了两种新的数据结构:Set和Map.Set是一组值的集合,其中值不能重复:Map(也叫字典)是一组键值对的集合,其中键不能重复.Set和Map都由哈希表(Hash Table)实现,并可按添 ...
- ES6躬行记(13)——类型化数组
类型化数组(Typed Array)是一种处理二进制数据的特殊数组,它可像C语言那样直接操纵字节,不过得先用ArrayBuffer对象创建数组缓冲区(Array Buffer),再映射到指定格式的视图 ...
- ES6躬行记(3)——解构
解构(destructuring)是一种赋值语法,可从数组中提取元素或从对象中提取属性,将其值赋给对应的变量或另一个对象的属性.解构地目的是简化提取数据的过程,增强代码的可读性.有两种解构语法,分别是 ...
- ES6躬行记(9)——字符串
在介绍字符串之前,有必要先了解一点Unicode的基础知识,有助于理解ES6提供的新功能和新特性. 一.Unicode Unicode是一种字符集(即多个字符的集合),它的目标是涵盖世界上的所有字符, ...
- ES6躬行记(7)——代码模块化
在ES6之前,由于ECMAScript不具备模块化管理的能力,因此往往需要借助第三方类库(例如遵守AMD规范的RequireJS或遵循CMD规范的SeaJS等)才能实现模块加载.而自从ES6引入了模块 ...
随机推荐
- redis的过期策略都有哪些?
1.面试题 redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现? 2.面试官心里分析 1)老师啊,我往redis里写的数据怎么没了? 之前有同学问过我,说我们生产环境的redi ...
- 借助Docker单机秒开数十万TCP连接
熟悉网络编程的都清楚系统只有65535个端口可用,1024以下的端口为系统保留,所以除去系统保留端口后可用的只有65411个端口,而一个TCP连接由TCP四元组(源IP.源端口.TCP.目标IP.目标 ...
- Tomcat6,7,8的日志切割
使用的日志切割工具cronolog(yum就可以了) 确定好路径后,开始配置 Tomcat6 Tomcat6/bin/catalina.sh 292-317行(修改两处) 修改之后为下面的内容 # t ...
- ES6新增对象方法的访问描述符:get(只读)、set(只写)
Es6新增对象方法的访问描述符:get(只读).set(只写),可以直接使用,一般用于数据监听,用途类似于vue.$watch. var obj = { a:1, get bar() { return ...
- NFS部署文件共享
本章解了如何配置网络文件系统(Network File System,NFS)服务来简化Linux系统之间的文件共享工作,以及通过部署NFS服务在多台Linux系统之间挂载并使用资源.在管理设备挂载信 ...
- C#单元测试,带你快速入门
注:本文示例环境 VS2017 XUnit 2.2.0 单元测试框架 xunit.runner.visualstudio 2.2.0 测试运行工具 Moq 4.7.10 模拟框架 为什么要编写单元测试 ...
- Atlas实现MySQL大表部署读写分离
序章 Atlas是360团队弄出来的一套基于MySQL-Proxy基础之上的代理,修改了MySQL-Proxy的一些BUG,并且优化了很多东西.而且安装方便.配置的注释写的蛮详细的,都是中文.英文不好 ...
- 最快效率求出乱序数组中第k小的数
题目:以尽量高的效率求出一个乱序数组中按数值顺序的第k 的元素值 思路:这里很容易想到直接排序然后顺序查找,可以使用效率较高的快排,但是它的时间复杂度是O(nlgn),我们这里可以用一种简便的方法,不 ...
- 美图App的移动端DNS优化实践:HTTPS请求耗时减小近半
本文引用了颜向群发表于高可用架构公众号上的文章<聊聊HTTPS环境DNS优化:美图App请求耗时节约近半案例>的部分内容,感谢原作者. 1.引言 移动互联网时代,APP 厂商之间的竞争非常 ...
- FFmpeg 学习(五):FFmpeg 编解码 API 分析
在上一篇文章 FFmpeg学习(四):FFmpeg API 介绍与通用 API 分析 中,我们简单的讲解了一下FFmpeg 的API基本概念,并分析了一下通用API,本文我们将分析 FFmpeg 在编 ...