文章目录
- Set([iterable])
-
- 属性
-
- Set.length
- get Set[@@species]
- Set.prototype
- 实例
-
- 属性
-
- Set.prototype.constructor
- Set.prototype.size
- 方法
-
- Set.prototype.add(value)
- Set.prototype.clear()
- Set.prototype.delete(value)
- Set.prototype.entries()
- Set.prototype.forEach(callbackFn[,thisArg])
- Set.prototype.has(value)
- Set.prototype.keys()
- Set.prototype.values()
- Set.prototype[@@iterator]()
- 应用
-
- 去除数组的重复成员
- 实现并集、交集和差集
- 在遍历操作中修改Set对象
- WeakSet
-
- 与Set的区别
- 属性
-
- WeakSet.length
- WeakSet.prototype
- 实例
-
- 属性
-
- WeakSet.prototype.constructor
- 方法
-
- WeakSet.prototype.add(value)
- WeakSet.prototype.delete(value)
- WeakSet.prototype.has(value)
- 注意
- 应用
Set([iterable])
本身是一个构造函数,用来生成Set数据结构。它可以存储任何类型的唯一值,无论是原始值或者是对象引用。
- Set结构不会添加重复的值。而且Set内部判断两个值是否不同,使用的算法和Object.is(v1,v2)的方法相同,类似于===,但是NaN等于自身。
- Set函数可使用iterator结构的对象作为参数来进行初始化
function outputSet(set){
for(let v of set){
console.log(v);
}
}
var s = new Set();
var arr = [1,23,4,5,6,4,3];
arr.map(a => s.add(a));
outputSet(s);
/*Output
1
23
4
5
6
3
*/
var initSet = new Set(arr);
outputSet(initSet);
/*Output
1
23
4
5
6
3
*/
利用其不会添加重复值的特点,去除重复值
var arr = [1,2,3,4,2,1,3,5,4,6,NaN,NaN];
arr = [...new Set(arr)];
console.log(arr);
//Output: [1, 2, 3, 4, 5, 6, NaN]
属性
Set.length
值为0
get Set[@@species]
构造函数用来创建派生对象
Set.prototype
表示Set构造器的原型,允许先所有Set对象添加新的属性。
实例
以下列代码为例
function outputSet(set){
for(let v of set){
console.log(v);
}
}
var arr = [1,2,4,5,2,5,4,3,5,4];
var expSet = new Set(arr);
属性
Set.prototype.constructor
返回实例的构造函数。默认情况下是Set()。
expSet.__proto__.constructor;
//result: ƒ Set() { [native code] }
Set.prototype.size
返回Set对象的值的个数
expSet.size
//result: 5
方法
Set.prototype.add(value)
在Set对象尾部添加一个元素。返回该Set对象
expSet.add("val");
outputSet(expSet);
/*Output:
1
2
4
5
3
val
*/
Set.prototype.clear()
移除Set对象内的所有元素
Set.prototype.delete(value)
移除Set对象中与这个值相等的元素,返回和
Set.prototype.has(value)
相同的结果。
- 如果Set对象中存在与这个值相等的元素,则返回true;
-
如果不存在,则返回false。
在运行之后,因为目标值已被删除,所以再次运行便为false。
expSet.delete("val");
//result: true
outputSet(expSet);
/*Output:
1
2
4
5
3
*/
expSet.delete("val");
//result: false
Set.prototype.entries()
返回一个新的迭代器对象,该对象包含Set对象中安插入顺序排列的所有元素的值的[value, value]数组。为了使这个方法和Map对象保持相似,每个值的键和值相等。
var obj = expSet.entries();
console.log(obj);
//Output: SetIterator {1 => 1, 2 => 2, 4 => 4, 5 => 5, 3 => 3}
Set.prototype.forEach(callbackFn[,thisArg])
按照顺序,为Set对象中的每一个值调用一次callbackFn。第二个参数是回调函数中的this会是这个参数。
var obj = {
arg: "arg"
};
var val = "";
expSet.forEach(function(x){
val += this.arg + x;
}, obj);
console.log(val);
//Output: "arg1arg2arg4arg5arg3";
Set.prototype.has(value)
返回一个布尔值,表示该值在Set中存在与否。
Set.prototype.keys()
与values()方法相同,返回一个新的额迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
expSet.keys();
//result: SetIterator {1, 2, 4, 5, 3}
Set.prototype.values()
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列所有元素的值。
expSet.values()
//result: SetIterator {1, 2, 4, 5, 3}
Set.prototype@@iterator
返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的所有元素的值。
应用
去除数组的重复成员
let arr = [1,2,1,2];
let arr2 = [...new Set(arr)];
实现并集、交集和差集
var a = new Set( [1,2,3,4] ),
b = new Set([4,5,6]);
//并集
let union = new Set([...a, ...b]);
//交集
let intersect = new Set([...a].filter(x => b.has(x)));
//差集
let diff = new Set([ ...[...a].filter(x => !b.has(x)), ...[...b].filter(x => !a.has(x))])
在遍历操作中修改Set对象
在遍历过程中,没有直接的方法。但是有以下两种方式。
- 利用原Set结构映射出一个新的结构,然后赋值给原来的Set结构
- 利用Array.from(Object[, fn]);
let set = new Set([1,2,3]);
set = new Set([...set].map(val => val * 2 ));
set = new Set([1,2,3]);
set = new Set(Array.from(set,val => val *2));
WeakSet
与Set的区别
- WeakSet的成员只能是对象
- WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用。即如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存。所以,无法引用WeakSet的成员,不可遍历WeakSet。
var ws = new WeakSet();
ws.add(1);
//result: Uncaught TypeError: Invalid value used in weak set
作为构造函数,WeakSet可以接收一个具有iterable接口的对象作为参数,让其自动成为WeakSet实例对象的成员。但是这个参数的成员必须为对象。一旦不是对象,那么,就会向上面代码那样报同样的错误。
var a = [[1,2],{val1: 3}];
var ws = new WeakSet(a);
console.log(ws);
//Output: WeakSet {Array(2), {…}}
属性
以以下代码为例
var ws = new WeakSet();
var obj1 = {};
WeakSet.length
值为0。实例该属性为undefined
console.log(WeakSet.length, ws.length);
//Output: 0 undefined
WeakSet.prototype
对应实例的所有继承属性和继承方法都在该对象上
实例
属性
WeakSet.prototype.constructor
返回构造函数即WeakSet本身。
方法
WeakSet.prototype.add(value)
在该WeakSet对象中添加一个新元素value,这个value必须是一个具有iterator接口的对象。
ws.add(obj1);
console.log(ws);
//Output: WeakSet {{…}}
WeakSet.prototype.delete(value)
从该WeakSet对象中删除value这个元素,之后WeakSet.prototype.has(value)方法会返回false
ws.delete(obj1);
console.log(ws);
//Output: WeakSet {}
WeakSet.prototype.has(value)
返回一个布尔值,表示给定的值value是否存在于这个WeakSet中。
ws.add(obj1);
ws.has(obj1);
//result: true
ws.delete(obj1);
//result: true
ws.has(obj1);
//result: false
注意
- WeakSet.prototype.clear() 已废弃,不再使用。
- WeakSet的成员不适合引用,因为它随时会消失,WeakSet内部有多少个成员,取决于垃圾回收机制有没有运行。所以规定了WeakSet不可遍历。也不会造成内存溢出的问题。
应用
- 存储DOM节点,不用担心节点从文档移除时会引发内存泄露。
- 保证构造函数的实例方法,只能在其实例上调用。这里使用WeakSet的好处是,foos对实例的引用,不会被计入内存回收机制,所以删除实例的时候,不用考虑foos,也不会出现内存泄露。
const foos = new WeakSet(); class Foo { constructor(){ foos.add(this); } method (){ if(!foos.has(this)){ throw new TypeError('Foo.prototype.method 只能在Foo的实例上调用!'); } } }
参考地址
http://caibaojian.com/es6/set-map.html
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Set
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/WeakSet
https://blog.csdn.net/jiandan1127/article/details/90670241