03月08, 2019

JS基础(4)——数据结构(4)——映射

映射(Map)也是 ECMAScript 6 规范中引入的一种数据结构。这是一种存储键值对列表很方便的方法,类似于其他编程语言中的词典或者哈希表。这一小节,让我们一起来看一下映射这种数据结构。

4-4-1 什么是映射

JavaScript 的对象(Object),本质上是键值对的集合(Hash结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。(我们会在第6章学习 JavaScript 里面的对象)

为了解决这个问题,ECMAScript 6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是"键"的范围不仅仅局限于字符串,而是各种类型的值(包括对象)都可以当作键。也就是说,Object 结构(对象结构)提供了"字符串—值"的对应,而 Map 结构提供了"值—值"的对应,是一种更完善的 Hash 结构的实现。

4-4-2 创建映射

使用new关键字与Map()构造函数,就可以创建一个空的 Map 对象。如果要向 Map 映射中添加新的元素,可以调用set()方法并分别传入键名和对应值作为两个参数。如果要从集合中获取信息,可以调用get()方法。具体示例如下:

let m = new Map();
m.set("name","zhangsan");
m.set("age",18);
console.log(m);
// Map { 'name' => 'zhangsan', 'age' => 18 }
console.log(m.get("name"));
// zhangsan

在对象中,无法用对象作为对象属性的键名。但是在 Map 映射中,却可以这样做,可以这么说,在 Map 映射里面可以使用任意数据类型来作为键。

let m = new Map();
m.set({},"zhangsan");
m.set([1,2,3],18);
m.set(3581,18);
console.log(m);
// Map { {} => 'zhangsan', [ 1, 2, 3 ] => 18, 3581 => 18 }

传入数组来初始化 Map 映射

可以向 Map 构造函数传入一个数组来初始化 Map 映射,这一点同样与 Set 集合相似。数组中的每个元素都是一个子数组,子数组中包含一个键值对的键名与值两个元素。因此,整个 Map 映射中包含的全是这样的两个元素的二维数组

let arr = [["name","zhangsan"],["age",18]];
let m = new Map(arr);
console.log(m);
// Map { 'name' => 'zhangsan', 'age' => 18 }

4-4-3 映射相关属性和方法

在设计语言新标准时,委员会为 Map 映射与 Set 集合设计了如下 3 个通用的方法:

has(key):检测指定的键名在Map映射中是否已经存在
delete(key):从Map映射中移除指定键名及其对应的值
clear():移除Map映射中的所有键值对

Map 映射同样支持size属性,其代表当前集合中包含的键值对数量

let arr = [["name","zhangsan"],["age",18]];
let m = new Map(arr);
console.log(m); // Map { 'name' => 'zhangsan', 'age' => 18 }
console.log(m.size); // 2
console.log(m.has("name")); // true
console.log(m.get("name")); // zhangsan
m.delete("name");
console.log(m); // Map { 'age' => 18 }
m.clear();
console.log(m); // Map {}

4-4-4 映射的遍历

与集合一样,映射也是可以枚举的,所以可以用与集合类似的方式进行遍历。

使用for-of来遍历映射:

let m = new Map([["name","zhangsan"],["age",18]]);
for(let i of m){
    console.log(i);
}
// [ 'name', 'zhangsan' ]
// [ 'age', 18 ]

keys()方法遍历映射的键:

let m = new Map([["name","zhangsan"],["age",18]]);
for(let i of m.keys()){
    console.log(i);
}
// name
// age

values()方法遍历映射的值:

let m = new Map([["name","zhangsan"],["age",18]]);
for(let i of m.values()){
    console.log(i);
}
// zhangsan
// 18

entries()方法同时遍历映射的键与值:

let m = new Map([["name","zhangsan"],["age",18]]);
for(let i of m.entries()){
    console.log(i);
}
// [ 'name', 'zhangsan' ]
// [ 'age', 18 ]

4-4-5 映射转为数组

Map 结构转为数组结构,比较快速的方法还是使用前面介绍过的扩展运算符...

let arr = [["name","zhangsan"],["age",18]];
let m = new Map(arr);
console.log([...m.keys()]); // [ 'name', 'age' ]
console.log([...m.values()]); // [ 'zhangsan', 18 ]
console.log([...m.entries()]); // [ [ 'name', 'zhangsan' ], [ 'age', 18 ] ]
console.log([...m]); // [ [ 'name', 'zhangsan' ], [ 'age', 18 ] ]

或者使用 Array 类的静态方法from()

let arr = [["name","zhangsan"],["age",18]];
let m = new Map(arr);
console.log(Array.from(m));
// [ [ 'name', 'zhangsan' ], [ 'age', 18 ] ]

4-4-6 弱映射(扩展)

弱映射和弱集合很类似,主要是解决存在映射里面的垃圾数据问题,创建弱映射使用new运算符以及WeakMap()构造函数,如下:

let weakMap = new WeakMap();

弱映射和普通映射一样,同样也具有has()get()set()delete()等方法。

总结

  1. 所谓数据结构,就是计算机存储和组织数据的方式。主要就是指将数据以什么样的结构存储到计算机里面。

  2. 数组是最常见的一种数据结构。在 JavaScript 里面创建数组可以通过字面量和构造函数两种方式来进行创建。

  3. 创建数组以后我们就可以对该数组进行赋值,访问和删除等操作。

  4. 解构是指将一个复杂类型的数据分解为普通类型的数据,在 JavaScript 中可以对数组和对象进行解构。

  5. JavaScript 中并不支持多维数组,但是我们可以利用动态语言的特性模拟出多维数组。

  6. ECMAScript 6 中新添加的扩展运算符,可以快速用于取出可迭代对象的每一项。

  7. 数组也拥有许多的属性和方法,掌握好这些属性和方法,可以让我们编写程序时事半功倍。

  8. 集合(Set)是 ECMAScript 6 中新引入的一种数据结构,它最大的特点就是不能包含重复值。

  9. 映射(Map)也是 ECMAScript 6 中新引入的一种数据结构,它是一种键值对结构,其最大的特点在于键可以是任意数据类型。

本文链接:http://www.yanhongzhi.com/post/js-basis-11.html

-- EOF --

Comments