Set()构造函数用来创建Set对象。Set对象类似于数据,其成员数据都是唯一的,没有重复的值,无论是基本数据类型还是对象类型。
Set本身是个构造函数,只能通过new操作符来进行构造函数调用,不能通过函数调用来创建Set对象。
如果不传递参数给Set构造函数,则创建一个空的Set。如果要传递参数,则这个参数必须是一个可迭代的对象,如数组或类数组对象。
new Set(iterable);
向Set中加入值的时候,不会进行类型转换。由于Set内部的值是唯一的,所以需要判断两个值是否相等。Set内部判断两个值是否相等所使用的算法类似于严格相等。但对NaN是例外,因为NaN始终不等于NaN,但在Set内部,NaN最多只能有一个值。
new Set(); // {}
new Set([1,2,3,3,4,4,5,5,5]); // {1, 2, 3, 4, 5}
Set的属性
Set本身有一个length属性,其值固定为0。有一个prototype属性对象,上有一个constructor属性,指向Set本身。
Set.length; // 0
Set.prototype.constructor === Set; // true
Set.prototype
Set本身没有提供任何方法。但Set.prototype属性对象上提供了若干的属性和方法,用于在Set实例上使用。
Set.prototype.size属性,表示Set实例对象中有多少个值。
Set.prototype.constructor属性返回创建实例的构造函数,默认就是Set构造函数本身。
Set.prototype还有9个方法:
(1)Set.prototype.add ( value ):添加某个值,返回Set结构本身。
(2) Set.prototype.clear ( ):清除所有数据成员。
(3) Set.prototype.has ( value ):返回一个布尔值,表示参数是否为Set的成员。
(4) Set.prototype.delete ( value ):删除某个值,返回一个布尔值表示是否删除成功。
(5) Set.prototype.keys ( ):返回一个键名的遍历器。
(6) Set.prototype.values ( ):返回一个键值的遍历器。
(7) Set.prototype.entries ( ):返回一个键值对的遍历器。
(8) Set.prototype.forEach ( callbackfn [ , thisArg ] ):使用回调函数遍历每个成员。
(9) Set.prototype [ @@iterator ] ( ):返回一个键值遍历器。
Set.prototype.add 方法
Set.prototype.add()方法用于向Set对象末尾添加一个指定的值,并返回Set对象本身。如果值已存在,则添加不会成功。
语法
set.add(value);
参数
value:要添加的值。
返回值
set对象本身。
示例
var set = new Set(); // 创建一个空的Set
set.add(1); // {1}
set.add(2); // {1,2}
set.add(3); // {1,2,3}
set.add(0); // {1,2,3,0}
set.add(-0); // {1,2,3,0}
set.add(1); // {1,2,3,0}
set.add(NaN); // {1,2,3,0,NaN}
set.add(null); // {1,2,3,0,NaN,null}
set.add(undefined); // {1,2,3,0,NaN,null,undefined}
set.add({}); // {1,2,3,0,NaN,null,undefined,{}}
set.add(NaN); // {1,2,3,0,NaN,null,undefined,{}}
set.add(null); // {1,2,3,0,NaN,null,undefined,{}}
set.add(undefined); // {1,2,3,0,NaN,null,undefined,{}}
set.add({}); // {1,2,3,0,NaN,null,undefined,{},{}}
Set.prototype.clear 方法
Set.prototype.clear()方法用来清空一个Set对象的所有元素,没有返回值。
示例
var set = new Set([1,2,3,4,5,6,5,6]);
set.size; // 6
set.clear();
set.size; // 0
Set.prototype.has 方法
Set.prototype.has()方法接受一个参数,返回一个布尔值,表明该参数是否存在于Set对象中。
语法
set.has(value);
参数
value:要检测的值
返回值
一个布尔值,表明该参数是否存在于Set对象中。
示例
var set = new Set([1,2,3,5,6,7, {}, null, undefined, NaN, -0]);
set.has(1); // true
set.has(null); // true
set.has(undefined); // true
set.has(NaN); // true
set.has(0); // true
set.has({}); // false,两个对象永远都不相等
set.has(); // false,并不会因为空调用而传入undefined
Set.prototype.delete 方法
Set.prototype.delete()接受一个参数,用来在Set实例中删除指定的值。返回一个布尔值,表明是否删除成功。
语法
set.delete(value);
参数
value:要从Set实例中删除的值
返回值
表明是否删除成功的布尔值。
示例
var set = new Set([1,null, undefined, {}, 0, NaN]);
set.delete(); // true
set.size; // 6
set; // {1, null, {}, 0, NaN}
set.delete(1); // true
set.delete(-0); // true
set.delete(NaN); // true
set.delete(undefined); // false
set.delete({}); // false
set.delete(null); // true
当进行空调用时,value的值为undefined,因此上实例中,第一个delete操作返回true,而此时set中已无undefined这个值,故在set.delete(undefined)的操作中,返回了false。
Set.prototype.keys 方法
Set.prototype.keys()返回Set实例对象的键名遍历器。但由于Set没有键名,只有键值,故keys()方法和Set.prototype.values()方法的返回值是一致的,也可以理解成keys()方法是values()方法的别名 (出于与 Map 对象保持相似的原因),返回的都是键值。
示例
var set = new Set([1,2,3,3,4,4,5,5,5]);
set; // {1, 2, 3, 4, 5}
var iter = set.keys();
iter.next().value; // 1
iter.next().value; // 2
iter.next().value; // 3
iter.next().value; // 4
iter.next().value; // 5
iter.next(); // undefined
Set.prototype.values 方法
Set.prototype.values()方法返回一个键值的遍历器。这个对象以插入Set 对象的顺序包含了原 Set 对象里的每个元素。
var set = new Set([1,2,3,3,4,4,5,5,5]);
set; // {1, 2, 3, 4, 5}
var iter = set.values();
iter.next().value; // 1
iter.next().value; // 2
iter.next().value; // 3
iter.next().value; // 4
iter.next().value; // 5
iter.next(); // undefined
Set.prototype.entries 方法
Set.prototype.entries()方法返回一个键值对的遍历器。由于Set对象实例没有键名,故返回的迭代器的每一项的值都是两个相同值组成的数组。
var set = new Set('abcde');
set; // {"a", "b", "c", "d", "e"}
var iter = set.entries();
iter.next().value; // ['a', 'a']
iter.next().value; // ['b', 'b']
iter.next().value; // ['c', 'c']
iter.next().value; // ['d', 'd']
iter.next().value; // ['e', 'e']
iter.next(); // undefined
Set.prototype.forEach 方法
Set.prototype.forEach()方法根据集合中元素的顺序,对每个元素都执行提供的回调函数一次,该方法没有返回值。
语法
set.forEach(func, thisArg);
参数
func:回调函数。Set对象的每个值都会执行一次这个函数。该函数接受3个参数,分别是元素的值,元素的索引和Set对象本身。由于Set对象没有索引,故该函数的第一个参数和第二个参数的值是一样的。
thisArg:func中绑定的this对象。如果不提供该值,在严格模式下是undefined,非严格模式下是全局对象。
示例1:输出Set对象中的值
var set = new Set('photoshop');
set.forEach(function (value, key) {
console.log("value:", value, "key:", key);
});
/*
value: p key: p
value: h key: h
value: o key: o
value: t key: t
value: s key: s
*/
示例2:在遍历过程中添加元素
var set = new Set('photoshop');
var i = 0;
set.forEach(function (value) {
if (i < 5) {
set.add(++i);
}
console.log("value:", value);
});
/*
value: p
value: h
value: o
value: t
value: s
value: 1
value: 2
value: 3
value: 4
value: 5
*/
在遍历过中添加的新元素会被遍历发现且处理。
示例3:在遍历过程中删除元素
var set = new Set('photoshop');
var i = 0;
var array = ["t", "s"];
set.forEach(function (value) {
if (i < 2) {
set.delete(array[i++]);
}
console.log("value:", value);
});
/*
value: p
value: h
value: o
*/
在遍历过程中删除未访问的元素,将无法再被访问到。
示例4:在遍历过程中先删除已访问元素,后再添加被删除的元素
var set = new Set('photoshop');
set; // {"p", "h", "o", "t", "s"}
var i = 0;
set.forEach(function (value) {
console.log("value:", value);
if (i == 0) {
set.delete('p');
} else if (i == 3) {
set.add('p');
}
i++;
});
/*
value: p
value: h
value: o
value: t
value: s
value: p
*/
set; // {"h", "o", "t", "s", "p"}
在遍历过程中删除已经访问过的元素,然后再进行添加,会在本次遍历中继续被访问到,此时已相当于是新增了一个元素。
Set.prototype[Symbol.iterator] 方法
该方法返回一个遍历器对象。其作用和Set.prototype.values()一致。
原文地址:https://zhuanlan.zhihu.com/p/53418464