JavaScript ES6 中全新的数据结构——Map图

终于,我们要说到ES6中最强大的功能------图Map

图是JavaScript中一种全新的数据结构。在图中你可以载入不同的数据类型,并为他们分配对应的键值。通过图可以很方便的对内部进行详细的数据操作,一些在对象中比较复杂的操作方式在图Map中会变得比较简单。

其次,相比于对象Object,图Map中的一个键只能出现一次,这样不仅可以减少不必要的关联,使得图数据处理具有更高的性能;在一定程度上也能降低因为键和值的滥用导致对象注入攻击,增强了数据结构的可靠性和安全性。

MDN官网上对于图Map的详细说明🔎:developer.mozilla.org/zh-CN/docs/...

创建一个图

和集合一样,你需要使用一个Map()构造函数创建一个图。并用set方法将键值keys和对应的内容Content传入到图内。

dart 复制代码
const rest = new Map(); //Create a null map // rest.set(/* key */, /* value */);
rest.set('name', 'LeeLin'); //arr.add()
rest.set(1, 'ZhaoCheng');
console.log(rest.set(2, 'Sam kong'));

如果你觉得频繁使用set方法很麻烦,图下的set方法同样支持一下写法:

bash 复制代码
rest
    .set('categories', ['意大利', '比萨店', '素食', '有机'])
    .set('open', 11)
    .set('close', 23)
    .set(true, 'We are open😀')
    .set(false, 'We are closed😴');

获取图Map中的内容

要想获取图中对应键值的内容,你需要使用Map下的get()方法即可获取。

实际上这两个方法非常好记,设置键值和其对应的值与内容使用set()方法,反过来获取键值对应的值和内容使用get()即可。

dart 复制代码
const rest = new Map(); //Create a null map // rest.set(/* key */, /* value */);
rest.set('name', 'LeeLin'); //arr.add()
rest.set(1, 'ZhaoCheng');
console.log(rest.set(2, 'Sam kong'));

rest
    .set('categories', ['意大利', '比萨店', '素食', '有机'])
    .set('open', 11)
    .set('close', 23)
    .set(true, 'We are open😀')
    .set(false, 'We are closed😴');

console.log(rest.get('name'));
console.log(rest.get(true));
console.log(rest.get(1));

另外,Map图中的get()使用方法非常灵活,例如下面我们可以直接在get()方法内插入逻辑表达式来对变量time进行判断。从得出的true或false映射到键值对应的内容,是'We are open😀'还是'We are closed😴'。

sql 复制代码
const time = 8;
console.log('test: ', 
    rest.get(time > rest.get('open') && time < rest.get('close'))); 
//true -> We are open😀

判断图中是否有相关键值对应的元素

在集合中同样使用的has()方法,在图Map数据结构中同样适用。你依然可以使用has()方法查找键值对应的内容。例如查询rest图中是否存在'categories'键值。

arduino 复制代码
console.log(rest.has('categories'));
console.log(rest);

下面列出三个和集合数据结构中一样的方法------delete删除、clear删除图中的全部内容、size计算图的大小。

删除图中的键值及其对应的元素

同样,在集合Set()中可以使用的delete方法,在Map图中也同样可以使用。

scss 复制代码
rest.delete(2);
console.log('Delete the key 2: ', rest);

清除图内容的所有元素

如有必要,你可以使用Map图下的clear方法清除图中的所有内容。注意此方法和集合Set()中的使用方法一样.

scss 复制代码
rest.clear();  // 图Map当然可以和集合一样,你也可以清空图中的内容
console.log('after clear the rest Map: ', rest);

计算图的大小

如果你想获取图中键对应的值占用图中多大空间------也就是图的大小是什么。你可以使用size()方法获取图的大小。

arduino 复制代码
console.log('OutPut the rest map size: ', rest.size); //7  //打印图的大小

关于图的键值

既然图中可以存放任何数据类型的变量和内容。实际上,图Map中的键值也可以有多种,甚至你可以将一个数组、一个HTML文本DOM对象定义为一个键值;并为他们映射到相关的内容上。

例如下面将数组arr键值映射到字符串'test'上。

c 复制代码
const arr = [1, 2];
rest.set(arr, 'Test');   // To call the reflected the key
rest.set(document.querySelector('h1'), 'Heading');  // Even you can control the DOM Object in the map
console.log('rest: ', rest);    // So we can use the object to call the value
console.log('rest.size: ', rest.size);

观察rest图内内容,你会发现键值数组[1,2]对应着字符串'Test'内容,而文本节点HTML中的DOM:h1对应的内容是字符串"Heading"。通过这个例子可以充分反映出JavaScript中图数据结构的多样性,其数据组成的松散性可以为构造大型的JavaScript应用程序及其web网络应用提供相当大的便利。

JavaScript中图Map的高级操作

在图中想设置键值和键值下的内容,我们需要使用set()方法来完成此操作。但如果我们要一次性的输入多个键值对应的内容,此时反复的使用set方法就会变的非常麻烦。有没有一种方法可以一次性的输入多个键和对应的值。

当然有,ES6中的图操作系统了一种非常简单的方式进行此操作。

使用Map构造函数一次性输入多个键和对应的值

css 复制代码
const question = new Map([    ['question', 'What is the best programming language in the world?'],
    [1, 'C'],
    [2, 'Java'],
    [3, 'JavaScript'],
    ['correct', 3],
    [true, 'Correct✅'],
    [false, 'Try again!'],
]);
console.log(question);

创建一个question的图,我们可以使用构造函数Map一次性将多个键和值传入question图中。另外,图中的每个键对应的内容都是用数组的形式进行封装。这个与JavaScript中的对象有非常大的区别。

并且用构造函数方法创建的Map同样可以使用has()、size()、delete()、clear()等方法。并且也可以使用for-of循环♻️对图Map进行操作。例如如果question图下的key键的类型是Number的话,就打印出该键值和其对应的内容。

javascript 复制代码
//Map 数据结构也是可迭代的🔁
console.log(question.get('question'));
for (const [key, value] of question) {
    if (typeof key === 'number') console.log(`Answer ${key}: ${value}`);
}

将对象Object转换成图Map

还记得对象和数组中的entries()方法吗,通过这个方法可以自动生成数字索引和对应的键值及其内容。这种数据结构对比图,你会发现两者有着异曲同工之妙,下面用伪代码来体现两者的异同。

ini 复制代码
/* 伪代码 */
console.log(Object.entries(obj));
/*
[Array(2),Array(2),Array(2)]
[
	0: ['content', {objCotnent1}],
  1: ['content', {objCotnent2}],
  2: ['content', {objCotnent3}],
]
*/
const test = new Map(
	['key','content'],
  [1,'content'],
  ['key','content'],
)
console.log(test);
/*
	Map{'key' => 'content', 1 => 'content', 'key' => 'content'}
	Map{
    0:{"key" => "content"}
    1:{1 => "content"}
    2:{"key" => "content"}
  }
*/

实际上,在图中一切键值和元素已经被分配好了对应的索引号。因此这也解释了为什么图结构Map也可以通过for-of循环♻️进行便利。

javascript 复制代码
// Convert object to map
console.log(Object.entries(openingHours));
const hoursMap = new Map(Object.entries(openingHours));
console.log(hoursMap);

将数组转换成图Map

同样使用ES6中的扩展语法可以...轻而易举的解构图Map中的内容,方便的将它们放置在数组中,形成一个数组结构。另外,图中的键和内容可以分开转换数组。(图中的键使用keys()方法,图中的值使用values()方法)。

ini 复制代码
//Convert map to array
console.log([...question]);
console.log(question.entries());
console.log([...question.keys()]);
console.log([...question.values()]);

关于图的其他操作

当然,像对象、数组、集合可以做的逻辑布尔操作、拷贝复制操作一样可以完成。你一样可以在图的get()方法中插入逻辑表达式进行分析和判断。例如下面这个例子中使用图下的get()方法对其进行逻辑表达式操作。

判断哪个是最好的编程语言 ,接收用户输入的数字,并将此数字与question图中对应的键进行比较。从而得出相应的结果。

ini 复制代码
//Guess which is the best programming language
const answer = Number(prompt('Your answer'));
// const answer = 3;
console.log(answer);

const tag = question.get('correct') === answer;
// console.log(tag);
console.log(question.get(tag));

图Map作为JavaScript ES6版本中的一个新的数据结构,其功能在某些方面(键和值的增删改查、获取大小、迭代🔁图内部的键和值)甚至可以替代对象Object数据类型。但在深拷贝方面,例如使用JSON.parse()下的JSON.Stringify()方法进行深拷贝操作,来实际操作对象中的内容而不是对象的副本。这种情况推荐使用对象。因为这种操作目前在图Map中仍比较麻烦。关于图Map数据结构肯定不是这样短短一篇文章就可以阐述清楚的,我会继续在实践中运用图Map结构,并进一步补充和完善这部分的内容。

未完持续...🎒

相关推荐
brien99 分钟前
为什么模型标称 1M,Google Antigravity 聊到 256K 却突然失忆?我们给它做了个原生行内监控圆环
前端
修炼的dance25 分钟前
录屏关键帧间隔多少合适?六档实测,2秒到10秒小了75.6%
前端
Lank_M31 分钟前
关键帧从1秒拉到10秒,录屏小87.3%,摄像头小10.8%
前端
补码缩写33 分钟前
用 ffprobe 拆录屏,八成字节在 29 个关键帧上
前端
百思不得小李35 分钟前
一个复杂的动态表单是如何实现的
前端·设计模式
陈随易1 小时前
Cmder 停更 17 个月,2.0 支持 Windows Terminal
前端·后端·程序员
清晨Coding1 小时前
删了 Cookie 还能自动登录?Google系网站登录态自动恢复的原理分析
javascript
风骏时光牛马1 小时前
前沿视界
前端
kyriewen1 小时前
我扫了 814 个依赖,97 个还敢要 Node 10
前端·javascript·程序员
陈随易1 小时前
3000 万人在用的翻译插件,重写一遍就是一门生意
前端·后端·程序员