准备ECMAScript 6:Set和WeakSet

在我最近的一篇名为《 为ECMAScript 6做准备:Map和WeakMap》中的文章中 ,我向您介绍了ECMAScript 6中可用的两种新数据类型: Map及其弱类WeakMap 。 在本教程中,我们将介绍另一个类似的数据类型,称为SetWeakSet 。 它们与MapWeakMap有很多相似之处,尤其是在可用方法方面。 但是,正如我们将在此处讨论的那样,它们具有不同的范围。

正如我在前面所有讨论ECMAScript 6的文章中所指出的那样,如果您想填充我们要介绍的内容,则可以使用Paul Miller的 es6-shim

Set

顾名思义, Set数据类型表示一组元素(一个集合)。 正如数学概念所暗示的,这意味着一个集合只允许您将相同的元素存储一次(例如,字符串“ test”不能存储两次)。 与其他JavaScript数据类型一样,存储相同类型的元素不是强制性的,因此在同一集合中可以存储数组,数字,字符串等。

还值得注意的是,例如使用get()方法无法检索集合中的单个元素。 原因是元素既没有键也没有索引,您可以引用该索引来检索它。 但是因为可以验证元素是否包含在给定的Set实例中,所以不需要get()方法。 例如,如果您知道字符串“ test”包含在集合中,则无需检索它,因为您已经具有该值。 正如您将在本教程中了解的那样,仍然可以检索所有存储的元素。

“但是什么时候适合这种数据类型?” 你可能会问。 好吧,假设您需要存储某些元素的ID。 在这些情况下,您不希望重复。 在这种情况下,在ECMAScript 5中,大多数人可能已经使用数组或对象来存储元素。 问题在于,每次引入新元素时,都必须检查是否尚未添加该元素,以避免重复。 如果使用数组,则将具有以下代码:

var collection = [1, 2, 3, 4, 5];
var newElements = [4, 8, 10];

for(var i = 0; i < newElements.length; i++) {
   if (collection.indexOf(newElements[i]) === -1) {
      collection.push(newElements[i]);
   }
}

使用Set数据类型,可以简化前面的代码,如下所示:

var collection = new Set([1, 2, 3, 4, 5]);
var newElements = [4, 8, 10];

for(var i = 0; i < newElements.length; i++) {
   collection.add(newElements[i]);
}

现在您知道Set是什么,以及何时使用它,让我们讨论所公开的属性和方法。

Set.prototype.size

size属性返回Set实例中的元素数。 这类似于Array数据类型的length

Set.prototype.constructor()

您可能知道,该构造函数用于实例化新对象。 它接受一个称为iterable的可选参数,它是一个数组或可迭代对象,其元素将添加到新集中。 使用的基本示例如下所示:

var array = [1, 2, "test", {a: 10}];
var set = new Set(array);

Set.prototype.add()

如果尚不存在,则add()方法将新元素添加到集合中。 否则不会添加该元素。 此方法的签名如下:

Set.prototype.add(value)

其中value是要存储的元素。 此方法修改了它所调用的集合,但还返回了新集合,允许链接。 下面显示了如何使用此功能的示例:

var set = new Set();
set.add("test").add(1).add({});

目前,此方法已在Firefox,Internet Explorer 11,Chrome 38和Opera 25中实现。在38之前的Chrome版本和25之前的Opera中,在激活“启用实验性JavaScript”标志之后,支持此方法。

Set.prototype.delete()

以相同的方式,我们可以添加元素,也可以从集合中删除它们。 为此,我们可以使用delete()方法。 它接受要删除的值,如果成功删除了该元素,则返回true否则返回false 。 该方法的签名如下所示:

Set.prototype.delete(value)

value表示要删除的元素。

目前,此方法已在Firefox,Internet Explorer 11,Chrome 38和Opera 25中实现。在38之前的Chrome版本和25之前的Opera中,您必须激活通常的标记。

Set.prototype.has()

has()方法是Set数据类型与Map共同的方法之一。 它允许我们验证元素是否存在于集合中。 如果找到该值,则返回true否则返回false 。 此方法的签名如下:

Set.prototype.has(value)

其中value是您要搜索的值。

目前,此方法已在Firefox,Internet Explorer 11,Chrome 38和Opera 25中实现。在38之前的Chrome版本和25之前的Opera中,在激活“启用实验性JavaScript”标志之后,支持此方法。

Set.prototype.clear()

与在Map定义的方法一样, clear()方法是从Set实例中删除所有元素的便捷方法。 该方法没有返回值(这意味着它返回undefined )。 clear()的签名如下所示:

Set.prototype.clear()

clear()当前在Firefox,Internet Explorer 11,Chrome 38和Opera 25中实现。在38之前的Chrome版本和25之前的Opera中,您必须激活通常的标志。

Set.prototype.forEach()

Map相同的另一种方法是forEach() 。 我们可以使用它来按插入顺序遍历存储在集合中的元素。 forEach()的签名如下:

Set.prototype.forEach(callback[, thisArg])

callback是在集合中的每个元素上运行的函数。 thisArg参数用于设置回调的上下文( this )。 callback接收三个参数:

  • value :处理的元素的值
  • value :处理的元素的值
  • set :处理Set对象

如您所见,正在处理的值传递了两次。 原因是使该方法与MapArray实现的forEach()保持一致。

Firefox,Internet Explorer 11,Chrome 38和Opera 25支持此方法。在38之前的Chrome和25之前的Opera的版本中,您必须激活通常的标志。

Set.prototype.entries()

entries()方法使我们能够获得一个Iterator以遍历集合的元素。 Iterator按插入顺序包含value数组-集合中每个元素的value对。 重复的原因与之前相同:使其与Map的方法保持一致。 此方法的签名是:

Set.prototype.entries()

Firefox,Chrome 38和Opera 25当前支持此方法。在38之前的Chrome版本和25之前的Opera中,您必须激活通常的标记。

Set.prototype.values()

属于此数据类型的另一种方法是values() 。 它按插入顺序返回一个Iterator对象,该对象包含集合中元素的值。 其签名如下:

Set.prototype.values()

Firefox,Chrome 38和Opera 25当前支持此方法。在38之前的Chrome版本和25之前的Opera的版本中,在激活“启用实验性JavaScript”标志之后支持此方法。

Set.prototype.keys()

奇怪的是, Set还有一个keys()方法。 它执行与values()相同的操作,因此我将不对其进行描述。

WeakSet

WeakSetSet数据类型的弱项。 WeakSet仅接受对象作为其值。 这意味着允许{}function(){} (函数继承自Object )和您自己的类的实例,但不允许使用"test"1和其他原始数据类型。

另一个重要的区别是,如果没有其他对对象的引用存储,则WeakSet对象不会阻止垃圾回收(该引用是weak )。 由于存在这种差异,因此没有任何一种方法可以一次检索值或一个以上的元素,例如Set.prototype.values()Set.prototype.entries() 。 另外,类似于WeakMap ,没有size属性可用。

最后一点,我想强调一点,Chrome 37和Opera 24支持WeakSet及其方法,但不带标志,而Set并非如此。 默认情况下,较新版本的Chrome 38和Opera 25支持Set及其方法。

全部放在一起

现在您已经了解了SetWeakSet数据类型的所有方法和属性,是时候将它们付诸实践了。 在本节中,我开发了两个演示,以便您可以使用这些方法并更好地了解它们的功能。 正如您将注意到的,我没有使用Set.prototype.keys()方法,因为我认为它仅能使开发人员感到困惑。

在第一个演示中,我将使用Set对象及其方法( Set.prototype.keys()除外Set.prototype.keys()

// Creates a new Set object
var set = new Set();
// Defines an array will be stored in the set
var arr = [4, 1, 9];

// Adds a new Number to the set
set.add(1);
// Adds a new String to the set
set.add('Aurelio De Rosa');
// Adds a new Object to the set
set.add({name: 'John Doe'});
// Adds a new Array element to the set
set.add(arr);

// Checks whether the string "test" is stored in the set. Prints "false"
console.log(set.has('test'));

// Checks whether the number "1" is stored in the set. Prints "true"
console.log(set.has(1));

// Retrieves the set size. Prints "4"
console.log(set.size);

// Deletes the object {name: 'Aurelio De Rosa'}. Prints "false" because even if it has the same values and properties, it's a different object
console.log(set.delete({name: 'Aurelio De Rosa'}));

// Retrieves the set size. Prints "4"
console.log(set.size);

// Deletes the array arr. Prints "true" because it's the same array
console.log(set.delete(arr));

// Retrieves the set size. Prints "3"
console.log(set.size);

// Loops over each element of the set
set.forEach(function(value, samevalue, set) {
    // Prints the value twice
    console.log('Value ' + value + ' is the same as ' + samevalue);
});

var entries = set.entries();
var entry = entries.next();
// Loops over each element of the set
while(!entry.done) {
    // Prints both the value and the key
    console.log('Value ' + entry.value[1] + ' is the same as ' + entry.value[0]);
    entry = entries.next();
}

var values = set.values();
var value = values.next();
// Loops over each value of the set
while(!value.done) {
    // Prints the value
    console.log('Value: ' + value.value);
    value = values.next();
}

// Deletes all the elements in the set
set.clear();

// Retrieves the set size. Prints "0"
console.log(set.size);

下面显示了先前代码的实时演示,并且还可以作为JSFiddle获得

在第二个演示中,我们将看到如何使用WeakSet对象。

// Creates a new WeakSet object
var weakset = new WeakSet();
// Defines an object that will be stored in the set
var obj = {name: 'Aurelio De Rosa'};

// Adds an object to the set
weakset.add(obj);
// Adds a function to the set
weakset.add(function(){});
// Adds another object to the set
weakset.add({name: 'John Doe'});

// Checks whether the Object {name: 'John Doe'} exists in the weak set. Prints "false" because despite the fact that the passed object and the stored one have the same values and properties, they are different objects
console.log(weakset.has({name: 'John Doe'}));

// Checks whether the Object obj exists in the weak set. Prints "true" because it's the same object
console.log(weakset.has(obj));

// Deletes the obj element. Prints "true"
console.log(weakset.delete(obj));

// Deletes the function(){} element. Prints "false" because the passed function and the stored one they are different functions (objects)
console.log(weakset.delete(function(){}));

// Deletes all the elements of the weak set
weakset.clear();

下面显示了先前代码的实时演示,并且还可以作为JSFiddle获得

结论

在本教程中,我介绍了新的SetWeakSet数据类型。 除了MapWeakMap之外,它们还是ECMAScript 6中可用的最有趣的新类型。希望您喜欢本文并学到一些有趣的东西。

From: https://www.sitepoint.com/preparing-ecmascript-6-set-weakset/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值