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>

原文地址:https://www.cnblogs.com/strick/p/10314395.html

时间: 2024-10-10 09:11:23

ES6躬行记(17)——Map的相关文章

ES6躬行记(7)——代码模块化

在ES6之前,由于ECMAScript不具备模块化管理的能力,因此往往需要借助第三方类库(例如遵守AMD规范的RequireJS或遵循CMD规范的SeaJS等)才能实现模块加载.而自从ES6引入了模块化标准后,就不需要再特地加载一次外部脚本了.模块化的语法不仅让JavaScript代码的组织变得更有条理,还包含封装.按需导出或导入等实用功能,可轻松应对日益复杂和庞大的前端工程.但有一点要注意,模块中的代码默认运行在严格模式中. 一.导出 一个模块就是一个独立的JavaScript文件,如果要读取

ES6躬行记(16)——Set

ES6引入了两种新的数据结构:Set和Map.Set是一组值的集合,其中值不能重复:Map(也叫字典)是一组键值对的集合,其中键不能重复.Set和Map都由哈希表(Hash Table)实现,并可按添加时候的顺序枚举. 一.Set Set类似于Array(数组),但需要通过SameValueZero算法保持值的唯一性.在前面的第11篇中,曾讲到Object.is()依据的比较算法是SameValue,SameValueZero算法与之类似,唯一的区别就是在该算法中,+0和-0是相等的. 1)创建

ES6躬行记(2)——扩展运算符和剩余参数

扩展运算符(Spread Operator)和剩余参数(Rest Parameter)的写法相同,都是在变量或字面量之前加三个点(...),并且只能用于包含Symbol.iterator属性的可迭代对象(iterable).虽然两者之间有诸多类似,但它们的功能和应用场景却完全不同.扩展运算符能把整体展开成个体,常用于函数调用.数组或字符串处理等:而剩余参数正好相反,把个体合并成整体,常用于函数声明.解构参数等.此处的整体可能是数组.字符串或类数组对象等,个体可能是字符.数组的元素或函数的参数等.

ES6躬行记(8)——数字

一.进制 ES6不仅完善了数字的八进制形式,还补充了一种十六进制形式,并且添加了全新的二进制形式.下面的三个变量分别表示八进制.十六进制和二进制的10,注释中给出了该进制的另一种写法. var octal = 0o12, //或0O12 hex = 0xa, //或0XA binary = 0b1010; //或0B1010 注意,只有十进制才能表示小数. 二.Number ES6不仅增强了Number对象处理数字的精度,还扩展了它的数字运算能力,新增的属性和方法如表2所示. 表2  Numbe

CSS躬行记(2)——伪类和伪元素

一.伪类选择器 伪选择器弥补了常规选择器的不足,能够实现一些特殊情况下的样式,例如在鼠标悬停时或只给字符串中的第一个字符指定样式.与类选择器类似,可以从HTML元素的class属性中查看到,但伪选择器不会出现在HTML文档中(有几个例外,如:lang.::placeholder等).并且它的关键字大小写不敏感,也就是说empty和EMPTY完全相同.伪选择器分为两种:伪类选择器和伪元素选择器.注意,伪选择器会以一个或两个冒号(:)开头,并且如果要与其它选择器组合使用,那么只能与类型选择器(即元素

React躬行记(5)——React和DOM

React实现了一套与浏览器无关的DOM系统,包括元素渲染.节点查询.事件处理等机制. 一.ReactDOM 自React v0.14开始,官方将与DOM相关的操作从React中剥离,组成单独的react-dom库,从而让React能兼容更多的终端.在引入react-dom库后,就能调用一个全局对象:ReactDOM,虽然在之前的章节中已多次使用该对象,但是都没有给出过多的讲解,本节将对其做重点分析. ReactDOM只包含了unmountComponentAtNode().findDOMNod

React躬行记(7)——表单

表单元素是一类拥有内部状态的元素,这些状态由其自身维护,通过这类元素可让用户与Web应用进行交互.HTML中的表单元素(例如<input>.<select>和<radio>等)在React中都有相应的组件实现,不仅如此,React还将它们分成两种:受控组件和非受控组件. 一.受控组件 受控组件(Controlled Component)是指那些受React控制的表单元素,其状态(value.checked等属性)的变更由组件的state管理.对于不同的表单元素,其受控组

Vue躬行记(2)——指令

Vue不仅内置了各类指令,包括条件渲染.事件处理等,还能注册自定义指令. 一.条件渲染 条件渲染的指令包括v-if.v-else.v-else-if和v-show. 1)v-if 该指令的功能和条件语句中的if类似,可根据表达式的计算结果,判断是否渲染分支中的元素和它所包含的子元素.在下面的示例中,当把数据对象的exist属性设为true时,<div>和<p>两个元素就会被添加到页面的DOM中. <div v-if="exist"> <p>

Vue躬行记(3)——样式和表单

Vue对DOM元素的class和style两个特性做了专门的增强,即对CSS类和内联样式做了一层封装,通过v-bind指令来处理它们,而接收的表达式既可以是简单的字符串.对象或数组,也可以是复杂的计算属性.不仅如此,Vue还为表单设计了一些语法糖,让表单处理变得尤为简单. 一.CSS类 v-bind指令与class参数配合,就能处理CSS类,并且能接收多种类型的值. 1)对象 v-bind:class可以接收一个对象,对象的属性名就是CSS类名,只有当其值是真值时,才能添加到DOM元素上,否则会