资讯专栏INFORMATION COLUMN

es6 Set和WeakSet

marser / 873人阅读

摘要:返回一个布尔值,表示该值是否为的成员。清除所有成员,没有返回值。上面代码中,方法返回的遍历器,同时包括键名和键值,所以每次输出一个数组,它的两个成员完全相等。因此,适合临时存放一组对象,以及存放跟对象绑定的信息。

Js大部分历史时期都只存在一种集合类型,也就是数组类型。数组在 JS 中的使用正如其他语言的数组一样,但缺少更多类型的集合导致数组也经常被当作队列与栈来使用。数组只使用了数值型的索引,而如果非数值型的索引是必要的,开发者便会使用非数组的对象。这种技巧引出了非数组对象的定制实现,即 Set 与 Map 。

Set: Set概述

Set对象是值的集合,你可以按照插入的顺序迭代它的元素。 Set中的元素只会出现一次,即 Set 中的元素是唯一的。

    Set结构类似于数组,但是没有重复结构 
 Set会自动移除重复的值,因此可以用来过滤数组中的重复结构
 Set内的对象是强引用
Set的构造:
a)    let set = new Set([1, 2, 3, 4]);

Set 构造器实际上可以接收任意可迭代对象作为参数。能使用数组是因为它们默认就是可迭代的,Set与Map也是一样,Set构造器会使用迭代器来提取参数中的值

b)    let set = new Set();

    set.add(1);
    set.add(2);
    set.add(2);
    //如果add对相同的值进行了多次调用,那么那么在第一次之后的调用实际上会被忽略
    set.add(3);
    set.add("3");

Set 不会使用强制类型转换来判断值是否重复。这意味着 Set 可以同时包含数值 3 与 字符串 "3" ,将它们都作为相对独立的项.
Set判断是否重复使用了Object.is() 方法,唯一的例外是 +0 与 -0 在 Set 中被判断为是相等的

c) 还可以向Set添加多个值相同的对象,他们不会被合并为同一项。

let set = new Set();
let key1 = {};
let key2 = {};
set.add(key1);
set.add(key2);
Set的属性及方法: 1、属性
Set.prototype.constructor:构造函数,默认就是Set函数。
Set.prototype.size:返回Set实例的成员总数。
2、方法

Set的方法分为两类:操作方法 和 遍历方法

2.1、操作方法:
•add(value):添加某个值,返回 Set 结构本身。
  因为返回set本身,所以可以写成:
  set.add(1).add(2).add(3)

•delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
 set.delete(2) ; // true

•has(value):返回一个布尔值,表示该值是否为Set的成员。
 set.has(2) ; // false

•clear():清除所有成员,没有返回值。
2.2、遍历方法:
forEach():使用回调函数遍历每个成员

es5给数组添加了forEach()方法,使得更容易处理数组中的每一项,没有返回值
对于数组来说forEach的三个参数:
arr[].forEach(function(value,index,array){//do})
value数组中的当前项, index当前项的索引, array原始数组

但是对于Set来说:

  let set2 = new Set([{"a":1}, {"b":2}]);
    set2.forEach(function(value, key, ownerSet) {
      console.log(ownerSet === set2);
      console.log(value === key);
    });

key 与 value 总是相同的,同时 ownerSet 也始终等于 set 。此代码输出:
true
true
true
true

如果想在回调函数中使用当前的this,还可以在forEach中传入this作为第二个参数

let set = new Set([1, 2]);
let processor = {
    output(value) {
    console.log(value);
  },
  process(dataSet) {
    dataSet.forEach(function(value) {
      this.output(value);
    }, this);
  }
};
processor.process(set);

本例中,在processor.process方法中的set调用了forEach方法,并传递了this作为第二个参数,这样便能正确的调用到this.output()方法
或者也可以使用箭头函数来达到相同的效果,无需传入this,只需将上边的process改写成:

process(dataSet) {
  dataSet.forEach((value) => this.output(value));
}
keys()、values()和entries()

keys():返回键名的遍历器
values():返回键值的遍历器
entries():返回键值对的遍历器

keys方法、values方法、entries方法返回的都是遍历器对象,由于Set结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

let set = new Set(["red", "green", "blue"]);

for (let item of set.keys()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.values()) {
  console.log(item);
}
// red
// green
// blue

for (let item of set.entries()) {
  console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

上面代码中,entries方法返回的遍历器,同时包括键名和键值,所以每次输出一个数组,它的两个成员完全相等。

Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。
Set.prototype[Symbol.iterator] === Set.prototype.values
// true
这就意味着,可以省略values方法,直接用for…of循环遍历Set

let set = new Set(["red", "green", "blue"]);

for (let x of set) {
  console.log(x);
}
// red
// green
// blue
Set常用场景

Set最经典的应用就是数组排重:

let set = new Set([1, 2, 3, 3, 3, 4, 5]),
array = [...set];
console.log(array);
Set与其他数据结构的互相转换 1、 Set与数组的转换 1.1、 Set转数组

使用扩展运算符可以很简单的将Set转成数组

let set = new Set([1, 2, 3, 3, 3, 4, 5]),
let array = [...set];
console.log(array); // [1,2,3,4,5]

该示例很好的说明了Set的一个重要的功能,数组排重,当然也很好的展示了,如何从Set转成数组的过程。
注意,这种转变是生成了一个新的数组对象原来的Set依然存在。

1.2、 数组转Set

如最初的构造示例:

let set = new Set([1,4,5,6,7]);
WeakSet:

由于 Set 类型存储对象引用的方式,它也可以被称为 Strong Set 。对象存储在 Set 的一个实例中时,实际上相当于把对象存储在变量中。只要对于 Set 实例的引用仍然存在,所存储的对象就无法被垃圾回收机制回收,从而无法释放内存。

当 JS 代码在网页中运行,同时你想保持与 DOM 元素的联系,在该元素可能被其他脚本移除的情况下,你应当不希望自己的代码保留对该 DOM 元素的最后一个引用(这种情况被称为内存泄漏)
为了缓解这个问题, ES6 也包含了 Weak Set ,该类型只允许存储对象弱引用,而不能存储基本类型的值。对象的弱引用在它自己成为该对象的唯一引用时,不会阻止垃圾回收。
WeakSet 里面的引用,都不计入垃圾回收机制,所以就不存在这个问题。因此,WeakSet 适合临时存放一组对象,以及存放跟对象绑定的信息。只要这些对象在外部消失,它在 WeakSet 里面的引用就会自动消失

WeakSet的构造:

Weak Set 使用 WeakSet 构造器来创建:

let set = new WeakSet(),
key = {};
// 将对象加入 set
set.add(key);
console.log(set.has(key)); // true
set.delete(key);
console.log(set.has(key)); // false
WeakSet的属性和方法:

基于WeakSet的弱引用特性,且里边的对象有可能随时消失的特性,es6规定WeakSet不可遍历,且没有size属性,WeakSet只有以下三个方法:
WeakSet.prototype.add(value):向 WeakSet 实例添加一个新成员。
WeakSet.prototype.delete(value):清除 WeakSet 实例的指定成员。
WeakSet.prototype.has(value):返回一个布尔值,表示某个值是否在 WeakSet 实例之中。

WeakSet的特性

对于 WeakSet 的实例,若调用add()方法时传入了非对象的参数,就会抛出错误(has()或delete()则会在传入了非对象的参数时返回false);

Weak Set 不可迭代,因此不能被用在 for-of 循环中;

Weak Set 无法暴露出任何迭代器; (例如 keys()与values() 方法,因此没有任何编程手段可用于判断 Weak Set 的内容);

Weak Set 没有 forEach() 方法;

Weak Set 没有 size 属性。

WeakSet之所以不可遍历是由于 WeakSet 内部有多少个成员,取决于垃圾回收机制有没有运行,运行前后很可能成员个数是不一样的,而垃圾回收机制何时运行是不可预测的,因此 ES6 规定 WeakSet 不可遍历。
WeakSet常用场景
Weak Set 看起来功能有限,而这对于正确管理内存而言是必要的。一般来说,若只想追踪对象的引用,应当使用 Weak Set 而不是正规 Set

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96832.html

相关文章

  • ES6 - WeakSet

    摘要:这几意味着,在初始化和调用的时候,都只能传入对象类型的元素。如果给方法传入非对象类型,会抛出错误。 在我们进入在WeakSet的使用之前,我们先来看一个用Set来存储对象引用的例子: let set = new Set(); let key = {}; set.add(key); key = null; console.log(set.size); // 1 console.log([...

    Jiavan 评论0 收藏0
  • 带你入门 JavaScript ES6 (五) 集合

    摘要:一概述集合是引入的新的内置对象类型,其特点同数学意义的集合,即集合内所有元素不重复元素唯一。数组集合对比数组和集合,数组可以加入重复数据,而集合的所有元素是唯一的不允许重复。因此,适合临时存放一组对象,以及存放跟对象绑定的信息。 本文同步带你入门 带你入门 JavaScript ES6 (五) 集合,转载请注明出处。 前面我们学习了: for of 变量和扩展语法 块作用域变量和解构...

    BetaRabbit 评论0 收藏0
  • 细说es6中的SetMap

    摘要:返回一个布尔值,表示该值是否为的成员。返回键名的遍历器返回键值的遍历器返回键值对的遍历器使用回调函数遍历每个成员需要特别指出的是,的遍历顺序就是插入顺序。该数组的所有成员,都会自动成为实例对象的成员。这意味着,数组的成员只能是对象。 1.Set ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。Set 本身是一个构造函数,用来生成 Set 数据结构...

    Ryan_Li 评论0 收藏0
  • 初探ES6中的SetweakSet

    摘要:对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。不能重复获取的值方法用来向一个对象的末尾添加一个指定的值。 Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。(不能重复) const set1=new Set([1,2,3,4,5,6]); console.log(set1); //Set { 1, 2, 3, 4, 5, 6 } 获取set的值 cons...

    afishhhhh 评论0 收藏0
  • ES6引入的数据结构 - ES6 - ECMAScript特性 - Javascript核心

    摘要:引入的数据结构新加入的数据类型有这些数据结构的支持并不广泛,在写这篇文章的时候。是或其他可枚举的对象,其每个元素是的元数组。开头的和不对持有引用,不影响。因此,他们没有办法对自身的进行直接的枚举。目前新版的和支持。 原文:http://pij.robinqu.me/JavaScript_Core/ECMAScript/es6/es6_data_types.html 源代...

    fobnn 评论0 收藏0

发表评论

0条评论

marser

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<