es6 集合

本文研究了四个新的ES6集合及其提供的好处。

大多数主要的编程语言都有几种类型的数据收集。 Python具有列表,元组和字典。 Java具有列表,集合,映射,队列。 Ruby具有哈希和数组。 到目前为止,JavaScript仅具有数组。 对象和数组是JavaScript的主力军。 ES6引入了四个新的数据结构,它们将为语言增加功能和表现力: MapSetWeakSetWeakMap

搜索JavaScript HashMap

HashMap,字典和散列是多种编程语言存储键/值对的几种方式,并且这些数据结构已针对快速检索进行了优化。

在ES5中,JavaScript对象(它们只是具有键和值的属性的任意集合)可以模拟哈希,但是将对象用作哈希一些不利之处

缺点1:密钥在ES5中必须为字符串

JavaScript对象属性键必须是字符串,这限制了它们用作各种数据类型的键/值对的集合的能力。 当然,您可以将其他数据类型强制/字符串化为字符串,但这会增加额外的工作。

缺点2:对象不是固有可迭代的

对象并非设计为用作集合,因此,没有有效的方法来确定对象具有多少个属性。 (例如,参见Object.keys是slow )。 遍历对象的属性时,还将获得其原型属性。 您可以将iterable属性添加到所有对象,但并非所有对象都应用作集合。 您可以使用for … in循环和hasOwnProperty()方法,但这只是一种解决方法。 当您遍历对象的属性时,不必按插入属性的顺序来检索属性。

缺点3:内置方法冲突带来的挑战

对象具有内置方法,如constructortoStringvalueOf 。 如果将其中之一添加为属性,则可能导致冲突。 您可以使用Object.create(null)创建一个裸对象(它不继承自object.prototype ),但是同样,这只是一种解决方法。

ES6包括新的集合数据类型,因此不再需要使用对象并避免它们的缺点。

使用ES6地图集

Map是我们要研究的第一个数据结构/集合。 映射是任何类型的键和值的集合。 创建新地图,添加/删除值,循环键/值并有效确定其大小非常容易。 以下是关键方法:

创建地图并使用常用方法

const map = new Map(); // Create a new Map
map.set('hobby', 'cycling'); // Sets a key value pair

const foods = { dinner: 'Curry', lunch: 'Sandwich', breakfast: 'Eggs' }; // New Object
const normalfoods = {}; // New Object

map.set(normalfoods, foods); // Sets two objects as key value pair

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(); // Clears key value pairs
console.log(map.size === 0); // True

在JSBin上运行此示例

使用集合集合

集是不包含重复项的值的有序列表。 使用键可以访问集,而不是像数组那样被索引。 JavaRubyPython和许多其他语言已经存在集合。 ES6集与其他语言中的集之间的区别是,顺序在ES6中很重要(在许多其他语言中不那么重要)。 这是关键的Set方法:

const planetsOrderFromSun = new Set();
planetsOrderFromSun.add('Mercury');
planetsOrderFromSun.add('Venus').add('Earth').add('Mars'); // Chainable Method
console.log(planetsOrderFromSun.has('Earth')); // True

planetsOrderFromSun.delete('Mars');
console.log(planetsOrderFromSun.has('Mars')); // False

for (const x of planetsOrderFromSun) {
  console.log(x); // Same order in as out - Mercury Venus Earth
}
console.log(planetsOrderFromSun.size); // 3

planetsOrderFromSun.add('Venus'); // Trying to add a duplicate
console.log(planetsOrderFromSun.size); // Still 3, Did not add the duplicate

planetsOrderFromSun.clear();
console.log(planetsOrderFromSun.size); // 0

在JSBin上运行此示例

弱集合,内存和垃圾集合

JavaScript垃圾回收是一种内存管理方式,通过该方式,不再引用的对象将自动删除,并回收其资源。

对对象的MapSet的引用被严格保留,并且不允许进行垃圾回收。 如果地图/集引用不再需要的大对象(例如已经从DOM中删除的DOM元素),则这可能会变得昂贵。




为了解决这个问题,ES6还引入了两个新的弱集合,称为WeakMapWeakSet 。 这些ES6集合“弱”是因为它们允许不再需要从内存中清除的对象。

弱地图

WeakMap是我们要介绍的新ES6集合中的第三个。 WeakMaps与普通Maps相似,尽管方法更少,并且在垃圾回收方面存在上述差异。

const aboutAuthor = new WeakMap(); // Create New WeakMap
const currentAge = {}; // key must be an object
const currentCity = {}; // keys must be an object

aboutAuthor.set(currentAge, 30); // Set Key Values
aboutAuthor.set(currentCity, 'Denver'); // Key Values can be of different data types

console.log(aboutAuthor.has(currentCity)); // Test if WeakMap has a key

aboutAuthor.delete(currentAge); // Delete a key

在JSBin上运行此示例

用例

WeakMaps 有几种流行的用例 。 它们可用于使对象的私有数据保持私有,也可用于跟踪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;
}());




es6取交集 es6 集合_大数据


<source type="image/webp"><source><img src="https://s2.51cto.com/images/blog/202406/21233056_66759cb0a681f54001.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_30,g_se,x_10,y_10,shadow_20,type_ZmFuZ3poZW5naGVpdGk=" alt="">



免费学习PHP!

全面介绍PHP和MySQL,从而实现服务器端编程的飞跃。

原价$ 11.95 您的完全免费


免费获得这本书


在这里使用WeakMap简化保持对象数据私有的过程。 可以引用Person对象,但是如果没有特定的Person实例,则不允许访问privateDataWeakMap

DOM节点用例

Google Polymer项目在名为PositionWalker的一段代码中使用WeakMaps

PositionWalker跟踪DOM子树中作为当前节点的位置以及该节点内的偏移量。

WeakMap用于跟踪DOM节点的编辑,删除和更改:

_makeClone() {
  this._containerClone = this.container.cloneNode(true);
  this._cloneToNodes = new WeakMap();
  this._nodesToClones = new WeakMap();

  ...

  let n = this.container;
  let c = this._containerClone;

  // find the currentNode's clone
  while (n !== null) {
    if (n === this.currentNode) {
    this._currentNodeClone = c;
    }
    this._cloneToNodes.set(c, n);
    this._nodesToClones.set(n, c);

    n = iterator.nextNode();
    c = cloneIterator.nextNode();
  }
}

弱集

WeakSets是Set集合,当不再需要它们引用的对象时,可以对其元素进行垃圾回收。 WeakSets不允许迭代。 他们的用例非常有限 (至少目前是这样)。 大多数早期采用者说, WeakSets用于标记对象而无需对其进行突变ES6-Features.org有一个示例,可以从WeakSet添加和删除元素 ,以便跟踪对象是否已被标记:

let isMarked     = new WeakSet()
let attachedData = new WeakMap()

export class Node {
    constructor (id)   { this.id = id                  }
    mark        ()     { isMarked.add(this)            }
    unmark      ()     { isMarked.delete(this)         }
    marked      ()     { return isMarked.has(this)     }
    set data    (data) { attachedData.set(this, data)  }
    get data    ()     { return attachedData.get(this) }
}

let foo = new Node("foo")

JSON.stringify(foo) === '{"id":"foo"}'
foo.mark()
foo.data = "bar"
foo.data === "bar"
JSON.stringify(foo) === '{"id":"foo"}'

isMarked.has(foo)     === true
attachedData.has(foo) === true
foo = null  /* remove only reference to foo */
attachedData.has(foo) === false
isMarked.has(foo)     === false

地图所有东西? 记录与ES6集合

映射和集合是键/值对的漂亮的ES6新集合。 也就是说,JavaScript对象在许多情况下仍可以用作集合。 除非情况需要,否则无需切换到新的ES6集合。

MDN有一个不错的问题列表,用于确定何时使用对象或键控集合:

  • 通常在运行时才知道密钥,您是否需要动态查找它们?
  • 所有值都具有相同的类型,并且可以互换使用吗?
  • 您是否需要不是字符串的键?
  • 是经常添加或删除键值对吗?
  • 您是否有任意数量(轻松更改)的键值对?
  • 集合是否迭代?

新的ES6集合产生了更有用JavaScript

JavaScript集合以前非常有限,但是ES6已对此进行了补救。 这些新的ES6集合将增加语言的功能和灵活性,并简化采用它们JavaScript开发人员的任务。


本文是Microsoft技术传播者和DevelopIntelligence的Web开发系列文章的一部分,内容涉及实用JavaScript学习,开源项目以及互操作性最佳实践,包括Microsoft Edge浏览器和新的EdgeHTML呈现引擎 DevelopIntelligence通过appendTo提供JavaScript培训React培训课程,它们是前端博客和课程站点。

我们鼓励您使用dev.microsoftedge.com上的免费工具(包括EdgeHTML问题跟踪器 )在包括EdgeEdge 问题跟踪器在内的所有浏览器和设备上进行测试,包括Microsoft Edge(Windows 10的默认浏览器) ,您可以在其中报告或搜索EdgeHTML问题,例如站点问题。渲染或符合标准。 另外, 请访问Edge博客以获取最新信息,并获得Microsoft开发人员和专家的最新信息。

翻译自: https://www.sitepoint.com/es6-collections-map-set-weakmap-weakset/

es6 集合