ES6에서는 두 가지 새로운 데이터 구조인 Set과 WeakSet을 제공합니다. Set은 배열과 비슷하지만, 멤버 변수의 값이 고유하고 중복되는 값이 없습니다. WeakSet은 고유한 값의 모음이기도 하지만 객체를 저장하는 데에만 사용할 수 있습니다.
1. 세트 활용
(1)Set 자체는 Set 데이터 구조를 생성하는 생성자를 제공합니다.
var s = new Set(); [2,2,2,5,8,16,2,1].map(x => s.add(x)) for(i of s){console.log(i)} //2,5,8,16,1
(2) Set() 함수는 초기화를 위한 생성 매개변수로 배열을 받아들일 수 있습니다.
var s = new Set([1,2,3,4,2,4,3]); [...s] //[1,2,3,4]
참고: Set에 값을 추가할 때 유형 변환이 발생하지 않으므로 5와 "5"는 두 개의 다른 값입니다. Set은 내부적으로 다음을 사용하여 두 값이 같은지 여부를 결정합니다. = ==, 이는 두 개체가 항상 동일하지 않음을 의미합니다. 목록 밖의 유일한 것은 NaN 자체입니다(정확한 항등 연산자는 NaN이 자신과 같지 않다고 간주합니다)
let set = new Set(); set.add({}) set.size//1 set.add({}) set.size//2
그러면 위 코드는 두 개의 빈 객체가 정확히 동일하지 않기 때문에 두 개의 다른 값을 갖는다는 것을 의미합니다.
(3)방법 및 속성 설정
(3.1)속성 설정
Set.prototype.size: Set 인스턴스의 구성원 수를 반환합니다.
Set.prototype.constructor: 기본 생성자 Set 함수입니다.
(3.2)동작 기능 설정
add(value): 값을 추가하고 Set 구조 자체를 반환합니다.
delete(value): 특정 값을 삭제하고 삭제 성공을 나타내는 Boolean 값을 반환합니다.
has(value): 매개변수가 Set의 멤버인지 여부를 나타내는 부울 값을 반환합니다.
clear(): 모든 멤버를 지우고 반환 값은 없습니다.
var set = new Set();
set.add(1).add(2).add(22).add(22);
set.size//3
set.hae(22)//true
set.has(4)//false
set.delete(2)//true
(3.3)순회 동작 설정
세트에는 네 가지 순회 방법이 있습니다. 멤버를 순회하는 데 사용할 수 있습니다.
키(): 키 이름 순회자를 반환합니다
값(): 값 탐색자를 반환합니다.
항목(): 키-값 쌍의 순회자를 반환합니다
forEach(): 콜백 함수를 사용하여 각 멤버를 순회합니다
참고: Set에는 키 이름이 없고 값 이름만 있으므로 키()와 값()이 반환하는 결과는 동일합니다.
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은 기본적으로 순회 가능하며 기본 순회자 생성 기능은 해당 값 방법입니다.
즉, value 메소드를 생략하고 for...of를 직접 사용해 순회할 수 있다는 뜻입니다.
var set = new Set([1,2,3,4]); for(let x of set){ console.log(x); } //1 //2 //3 //4
확산 연산자(...)를 사용하면 내부적으로 for...of 루프가 사용되므로 Set 구조에도 사용할 수 있습니다.
let set = new Set(['red','green','blue']); let arr = [...set]; //['red','green','blue'];
(3.4)세트는 합집합, 교차점, 차이 세트를 구현합니다
let set1 = new Set([1,2,3,4,5,6]); let set2 = new Set([4,5,6,7,8,9]); //并集 let union = new Set([...set1,...set2]); //[1,2,3,4,5,6,7,8,9] //交集 let intersect = new Set([...set1].filter(x => b.has(s))); //[4,5,6] //差集 let intersect = new Set([...set1].filter(x => !b.has(s))); //[1,2,3,4]
(3.5)Set은 forEach 사용을 구현합니다
let set = new Set([1,2,3,4,5,6]); set.forEach(value,key)=>consloe.log(vlaue+1); //2 //3 //4 //5 //6 //7
참고: forEach 메서드의 매개 변수는 처리 함수이며 이는 (키 값, 키 이름) 컬렉션 자체입니다. 또한 forEach 메서드에는 이 메서드가 바인딩되는 개체를 나타내는 두 번째 매개 변수가 있습니다.
2. WeakSet 사용
WeakSet은 Set과 유사하며 반복되지 않는 값의 모음이기도 합니다. 그러나 객체를 저장하는 데에만 사용할 수 있습니다. 다른 유형의 값일 수 없습니다.
WeakSet은 생성자입니다. 배열 및 배열 유사 객체를 인수로 받아들일 수 있습니다. (실제로 반복 가능한 인터페이스가 있는 모든 객체는 WeakSet의 매개변수로 사용될 수 있습니다.) 배열의 모든 멤버는 자동으로 WeakSet 인스턴스 개체의 멤버가 됩니다.
var a = 새로운 [[1,2],[3,4]]
var ws = 새로운 WeakSet(a);
var ws = new WeakSet(); ws.add(1);//TypeError:Invalid value used in weak set ws.add(Symbol);//TypeError:Invalid value used in weak set
값과 기호를 추가하면 오류가 동시에 보고됩니다.
WeakSet 구조에는 다음과 같은 메소드가 있습니다
WeakSet.protoptype.add(value): WeakSet 인스턴스에 새 멤버를 추가합니다.
WeakSet.protoptype.delete(value): WeakSet 인스턴스의 지정된 멤버를 삭제합니다.
WeakSet.protoptype.has(value): 값이 WeakSet 인스턴스에 있는지 여부를 나타내는 부울 값을 반환합니다.
var ws = new WeakSet(); var obj = {}; var foo = {}; ws.add(window); ws.add(obj); ws.has(window);//true ws.has(foo);false ws.delete(window);//true ws.has(window);//false
WeakSet은 멤버가 약한 참조이고 언제든지 사라질 수 있으므로 순회할 수 없습니다. 순회가 완료된 직후에는 해당 멤버를 더 이상 사용할 수 없을 수도 있습니다. WeakSet의 한 가지 용도는 DOM 노드가 문서에서 제거될 때 메모리 누수에 대한 걱정 없이 DOM 노드를 저장하는 것입니다.