本文探讨了四个新的ES6集合以及它们带来的好处。
大多数主要的编程语言都有几种类型的数据集合。Python有列表、元组和字典。Java有列表、集合、映射、队列。Ruby有哈希和数组。到目前为止,JavaScript只有数组。对象和数组是JavaScript的得力助手。ES6引入了四个新的数据结构,它们将增强语言的强大功能和表达能力:Map、Set、WeakSet和WeakMap。
关键要点
- ES6引入了四个新的数据结构:Map、Set、WeakSet和WeakMap。这些集合允许更具表达性和功能强大的JavaScript编程。
- ES6中的Map和Set是任何类型的键值对的集合。它们针对快速检索进行了优化,并提供添加、删除和循环遍历值的方法。但是,它们对对象持有强引用,如果对象很大且不再需要,则可能代价很高。
- ES6还引入了WeakMap和WeakSet,它们类似于Map和Set,但对对象持有弱引用。这意味着当这些对象不再需要时,可以对其进行垃圾回收,这对于内存管理非常有益。
- 虽然新的ES6集合提供了更大的灵活性,但在许多情况下,JavaScript对象仍然可以用作集合。在决定是否使用对象或键控集合时,开发人员应考虑诸如需要动态键查找、值的互换性和添加或删除键值对的频率等因素。
寻找JavaScript HashMap
HashMap、字典和哈希是各种编程语言存储键值对的几种方法,这些数据结构针对快速检索进行了优化。
在ES5中,JavaScript对象(只是具有键和值的属性的任意集合)可以模拟哈希,但是使用对象作为哈希有几个缺点。
缺点#1:ES5中的键必须是字符串
JavaScript对象属性键必须是字符串,这限制了它们作为不同数据类型键值对集合的能力。当然,您可以将其他数据类型强制转换为字符串,但这会增加额外的工作。
缺点#2:对象并非天生可迭代
对象并非设计为集合,因此没有有效的方法来确定对象有多少属性。(例如,Object.keys速度很慢)。当您循环遍历对象的属性时,您还会获得其原型属性。您可以向所有对象添加可迭代属性,但并非所有对象都旨在用作集合。您可以使用for … in循环和hasOwnProperty()方法,但这只是一个变通方法。当您循环遍历对象的属性时,属性不一定会按照插入的顺序检索。
缺点#3:内置方法冲突的挑战
对象具有内置方法,如constructor、toString和valueOf。如果将其中一个添加为属性,则可能导致冲突。您可以使用Object.create(null)创建一个裸对象(不继承自object.prototype),但这仍然只是一个变通方法。
ES6包含新的集合数据类型,因此不再需要使用对象并忍受它们的缺点。
使用ES6 Map集合
Map是我们将要检查的第一个数据结构/集合。Map是任何类型的键值对的集合。创建新的Map、添加/删除值、循环遍历键/值以及有效地确定其大小很容易。以下是关键方法:
创建映射并使用常用方法
const map = new Map(); // 创建一个新的Map map.set('hobby', 'cycling'); // 设置键值对 const foods = { dinner: 'Curry', lunch: 'Sandwich', breakfast: 'Eggs' }; // 新对象 const normalfoods = {}; // 新对象 map.set(normalfoods, foods); // 设置两个对象作为键值对 for (const [key, value] of map) { console.log(`${key} = ${value}`); // hobby = cycling [object Object] = [object Object] } map.forEach((value, key) => { console.log(`${key} = ${value}`); }, map); // hobby = cycling [object Object] = [object Object] map.clear(); // 清除键值对 console.log(map.size === 0); // True
在JSBin上运行此示例
使用Set集合
Set是有序的值列表,不包含重复项。Set不是像数组那样被索引,而是使用键访问。Set已经存在于Java、Ruby、Python和许多其他语言中。ES6 Set与其他语言中的Set之间的一个区别是,顺序在ES6中很重要(在许多其他语言中并非如此)。以下是关键的Set方法:
const planetsOrderFromSun = new Set(); planetsOrderFromSun.add('Mercury'); planetsOrderFromSun.add('Venus').add('Earth').add('Mars'); // 可链式方法 console.log(planetsOrderFromSun.has('Earth')); // True planetsOrderFromSun.delete('Mars'); console.log(planetsOrderFromSun.has('Mars')); // False for (const x of planetsOrderFromSun) { console.log(x); // 输入和输出顺序相同 - Mercury Venus Earth } console.log(planetsOrderFromSun.size); // 3 planetsOrderFromSun.add('Venus'); // 尝试添加重复项 console.log(planetsOrderFromSun.size); // 仍然是3,没有添加重复项 planetsOrderFromSun.clear(); console.log(planetsOrderFromSun.size); // 0
在JSBin上运行此示例
弱集合、内存和垃圾回收
JavaScript垃圾回收是一种内存管理形式,其中不再引用的对象会自动删除,并且其资源会被回收。
Map和Set对对象的引用是强持有的,并且不允许垃圾回收。如果map/set引用不再需要的大的对象(例如已经从DOM中删除的DOM元素),这可能会变得很昂贵。
为了解决这个问题,ES6还引入了两个新的弱集合,称为WeakMap和WeakSet。这些ES6集合是“弱”的,因为它们允许不再需要的对象从内存中清除。
WeakMap
WeakMap是我们介绍的第三个新的ES6集合。WeakMap类似于普通的Map,但方法较少,并且在垃圾回收方面存在上述差异。
const aboutAuthor = new WeakMap(); // 创建新的WeakMap const currentAge = {}; // 键必须是对象 const currentCity = {}; // 键必须是对象 aboutAuthor.set(currentAge, 30); // 设置键值 aboutAuthor.set(currentCity, 'Denver'); // 键值可以是不同数据类型 console.log(aboutAuthor.has(currentCity)); // 测试WeakMap是否包含键 aboutAuthor.delete(currentAge); // 删除键
使用案例
WeakMap有几个流行的用例。它们可以用来保持对象的私有数据私有,也可以用来跟踪DOM节点/对象。
私有数据用例
以下示例来自JavaScript专家Nicholas C. Zakas:
var Person = (function() { var privateData = new WeakMap(); function Person(name) { privateData.set(this, { name: name }); } Person.prototype.getName = function() { return privateData.get(this).name; }; return Person; }());
在这里使用WeakMap简化了保持对象数据私有的过程。可以引用Person对象,但是如果没有特定的Person实例,则不允许访问privateDataWeakMap。
DOM节点用例
Google Polymer项目在一个名为PositionWalker的代码片段中使用WeakMap。
PositionWalker跟踪DOM子树中的位置,作为当前节点和该节点内的偏移量。
WeakMap用于跟踪DOM节点的编辑、删除和更改:
const map = new Map(); // 创建一个新的Map map.set('hobby', 'cycling'); // 设置键值对 const foods = { dinner: 'Curry', lunch: 'Sandwich', breakfast: 'Eggs' }; // 新对象 const normalfoods = {}; // 新对象 map.set(normalfoods, foods); // 设置两个对象作为键值对 for (const [key, value] of map) { console.log(`${key} = ${value}`); // hobby = cycling [object Object] = [object Object] } map.forEach((value, key) => { console.log(`${key} = ${value}`); }, map); // hobby = cycling [object Object] = [object Object] map.clear(); // 清除键值对 console.log(map.size === 0); // True
WeakSet
WeakSet是其元素在不再需要它们引用的对象时可以进行垃圾回收的Set集合。WeakSet不允许迭代。它们的用例相当有限(至少目前是这样)。大多数早期采用者说WeakSet可以用来标记对象而无需修改它们。ES6-Features.org有一个从WeakSet添加和删除元素的示例,以便跟踪对象是否已被标记:
const planetsOrderFromSun = new Set(); planetsOrderFromSun.add('Mercury'); planetsOrderFromSun.add('Venus').add('Earth').add('Mars'); // 可链式方法 console.log(planetsOrderFromSun.has('Earth')); // True planetsOrderFromSun.delete('Mars'); console.log(planetsOrderFromSun.has('Mars')); // False for (const x of planetsOrderFromSun) { console.log(x); // 输入和输出顺序相同 - Mercury Venus Earth } console.log(planetsOrderFromSun.size); // 3 planetsOrderFromSun.add('Venus'); // 尝试添加重复项 console.log(planetsOrderFromSun.size); // 仍然是3,没有添加重复项 planetsOrderFromSun.clear(); console.log(planetsOrderFromSun.size); // 0
Map所有事物?记录与ES6集合
Map和Set是键值对的漂亮的新ES6集合。也就是说,JavaScript对象仍然可以在许多情况下用作集合。除非情况需要,否则无需切换到新的ES6集合。
MDN有一个很好的问题列表,用于确定何时使用对象或键控集合:
- 键通常直到运行时才知道吗?您需要动态查找它们吗?
- 所有值都具有相同的类型,并且可以互换使用吗?
- 您是否需要不是字符串的键?
- 经常添加或删除键值对吗?
- 您是否有任意数量(易于更改)的键值对?
- 集合是否被迭代?
新的ES6集合产生更易用的JavaScript
JavaScript集合以前非常有限,但这已通过ES6得到纠正。这些新的ES6集合将增强语言的强大功能和灵活性,并简化采用它们的JavaScript开发人员的任务。
本文是来自Microsoft技术布道者和DevelopIntelligence关于实用JavaScript学习、开源项目和互操作性最佳实践(包括Microsoft Edge浏览器和新的EdgeHTML渲染引擎)的Web开发系列的一部分。DevelopIntelligence通过appendTo(其专注于前端的博客和课程网站)提供JavaScript培训和React培训课程。
我们鼓励您在包括Microsoft Edge(Windows 10的默认浏览器)在内的各种浏览器和设备上进行测试,可以使用dev.microsoftedge.com上的免费工具,包括EdgeHTML问题跟踪器,您可以在其中报告或搜索EdgeHTML问题,例如网站渲染或标准合规性问题。此外,请访问Edge博客,以获取来自Microsoft开发人员和专家的最新信息。
关于ES6集合的常见问题解答 (FAQ):Map、Set、WeakMap、WeakSet
JavaScript ES6中Map和WeakMap的主要区别是什么?
在JavaScript ES6中,Map和WeakMap都用于存储键值对。但是,它们之间存在一些显着差异。首先,在Map中,键可以是任何类型,而在WeakMap中,键必须是对象。其次,Map具有size属性,允许您检查键值对的数量,但WeakMap没有此属性。最后,Map对键对象持有强引用,这意味着只要Map存在,它们就没有资格进行垃圾回收。另一方面,WeakMap对键对象持有弱引用,这意味着如果对对象没有其他引用,则可以对其进行垃圾回收。
如何在JavaScript ES6中迭代WeakMap或WeakSet?
与Map和Set不同,WeakMap和WeakSet没有迭代其元素的方法。这是因为它们旨在对它们的键(WeakMap)或值(WeakSet)持有弱引用,这意味着这些可以在任何时间进行垃圾回收。因此,无法保证在尝试迭代元素时元素仍然存在。如果您需要迭代集合,则应改用Map或Set。
我可以在WeakMap或WeakSet中使用原始数据类型作为键吗?
不可以,您不能在WeakMap或WeakSet中使用原始数据类型作为键。这些集合中的键必须是对象。这是因为WeakMap和WeakSet对它们的键持有弱引用,这意味着如果对它们没有其他引用,则可以对键进行垃圾回收。原始数据类型(例如数字和字符串)不会像对象那样进行垃圾回收,因此它们不能用作这些集合中的键。
为什么我应该使用WeakMap或WeakSet而不是Map或Set?
WeakMap和WeakSet具有一些独特的特性,在某些情况下,它们可能比Map或Set更合适。因为它们对它们的键(WeakMap)或值(WeakSet)持有弱引用,所以当它们不再使用时,可以对其进行垃圾回收。如果您想将其他数据与对象关联,但又不想阻止对象在不再需要时进行垃圾回收,这将非常有用。此外,因为WeakMap和WeakSet没有迭代其元素的方法,所以它们可以为它们存储的数据提供一定程度的隐私。
当WeakMap或WeakSet中的键被垃圾回收时会发生什么?
当WeakMap或WeakSet中的键被垃圾回收时,集合中的相应条目会自动删除。这是因为这些集合对它们的键持有弱引用,这意味着当它们不再使用时,可以对键进行垃圾回收。此功能对于管理JavaScript应用程序中的内存非常有用,因为它确保与不再使用的对象关联的数据也会被清除。
我可以使用WeakMap或WeakSet来存储临时数据吗?
是的,WeakMap和WeakSet非常适合存储临时数据。因为它们对它们的键(WeakMap)或值(WeakSet)持有弱引用,所以当它们不再使用时,可以对其进行垃圾回收。这意味着当键被垃圾回收时,存储在这些集合中的数据也会被清除。这对于存储仅在短时间内需要的有用,因为您不必担心手动清理它。
如何检查WeakMap或WeakSet是否包含某个键或值?
您可以使用has方法来检查WeakMap或WeakSet是否包含某个键。此方法返回一个布尔值,指示该键是否存在于集合中。但是,请记住,您不能使用此方法来检查WeakSet中的某个值,因为此集合中的值是不可访问的。
我可以从WeakMap或WeakSet中删除条目吗?
是的,您可以使用delete方法从WeakMap中删除条目。此方法删除与给定键关联的条目,并返回一个布尔值,指示该键是否存在于集合中。但是,您不能从WeakSet中删除条目,因为此集合没有delete方法。
我可以清除WeakMap或WeakSet中的所有条目吗?
不可以,您不能清除WeakMap或WeakSet中的所有条目。这些集合没有clear方法,该方法在Map和Set中可用。这是因为WeakMap和WeakSet旨在在键被垃圾回收时自动清理它们的条目。
我可以获取WeakMap或WeakSet的大小吗?
不可以,您无法获取WeakMap或WeakSet的大小。这些集合没有size属性,该属性在Map和Set中可用。这是因为由于垃圾回收,WeakMap或WeakSet的大小可以随时更改。
以上是ES6集合:使用地图,设置,弱图,弱点的详细内容。更多信息请关注PHP中文网其他相关文章!

Python和JavaScript各有优势,选择取决于项目需求和个人偏好。1.Python易学,语法简洁,适用于数据科学和后端开发,但执行速度较慢。2.JavaScript在前端开发中无处不在,异步编程能力强,Node.js使其适用于全栈开发,但语法可能复杂且易出错。

javascriptisnotbuiltoncorc; saninterpretedlanguagethatrunsonenginesoftenwritteninc.1)javascriptwasdesignedAsalightweight,解释edganguageforwebbrowsers.2)Enginesevolvedfromsimpleterterterpretpreterterterpretertestojitcompilerers,典型地提示。

JavaScript可用于前端和后端开发。前端通过DOM操作增强用户体验,后端通过Node.js处理服务器任务。1.前端示例:改变网页文本内容。2.后端示例:创建Node.js服务器。

选择Python还是JavaScript应基于职业发展、学习曲线和生态系统:1)职业发展:Python适合数据科学和后端开发,JavaScript适合前端和全栈开发。2)学习曲线:Python语法简洁,适合初学者;JavaScript语法灵活。3)生态系统:Python有丰富的科学计算库,JavaScript有强大的前端框架。

JavaScript框架的强大之处在于简化开发、提升用户体验和应用性能。选择框架时应考虑:1.项目规模和复杂度,2.团队经验,3.生态系统和社区支持。

引言我知道你可能会觉得奇怪,JavaScript、C 和浏览器之间到底有什么关系?它们之间看似毫无关联,但实际上,它们在现代网络开发中扮演着非常重要的角色。今天我们就来深入探讨一下这三者之间的紧密联系。通过这篇文章,你将了解到JavaScript如何在浏览器中运行,C 在浏览器引擎中的作用,以及它们如何共同推动网页的渲染和交互。JavaScript与浏览器的关系我们都知道,JavaScript是前端开发的核心语言,它直接在浏览器中运行,让网页变得生动有趣。你是否曾经想过,为什么JavaScr

Node.js擅长于高效I/O,这在很大程度上要归功于流。 流媒体汇总处理数据,避免内存过载 - 大型文件,网络任务和实时应用程序的理想。将流与打字稿的类型安全结合起来创建POWE

Python和JavaScript在性能和效率方面的差异主要体现在:1)Python作为解释型语言,运行速度较慢,但开发效率高,适合快速原型开发;2)JavaScript在浏览器中受限于单线程,但在Node.js中可利用多线程和异步I/O提升性能,两者在实际项目中各有优势。


热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

EditPlus 中文破解版
体积小,语法高亮,不支持代码提示功能

WebStorm Mac版
好用的JavaScript开发工具

DVWA
Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

mPDF
mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

Atom编辑器mac版下载
最流行的的开源编辑器