2019-07-17 es6(4) - Map, Set

  • es6에서 값들을 효과적으로 매핑하기 위해 Map구조를 도입하였다.
  • Map객체에 저장되어있는 각 요소들을 [key, value]형태로 for…of를 사용해서 접근을 할 수 있다.
  • java에서는 Map구조에서 key값을 hash저장하기때문에 동일한 hash에 대한 키값은 저장을 못한다. 반면 js에서는 엔진이 별도의 일렬번호를 부여하고 이를 통해 순서를 보장해준다.
  • 중복된 key를 통해서 추가하는 경우 해당 key의 value값을 덮어쓴다.(기존 key의 순서를 유지) ``` var sayings = new Map(); sayings.set(“dog”, “woof”); sayings.set(“cat”, “meow”); sayings.set(“elephant”, “toot”); sayings.size; // 3 sayings.get(“fox”); // undefined sayings.has(“bird”); // false sayings.delete(“dog”);

for (var [key, value] of sayings) { console.log(key + “ goes “ + value); } // “cat goes meow” // “elephant goes toot”


## Object와 Map의 비교

- 이전에는 Object의 String key를 이용해서 값을 매핑을 했다.
- Object의 키는 String이지만 Map은 모든 값을 가질 수 있다.
- Object는 크기를 수동으로 추적하지만 Map은 자동으로 알 수 있다.
- Map은 삽입된 순서대로 반복이 된다.

### 언제 Map, Object를 쓰는가
- 실행 시까지 키를 알 수 없고, 모든 키가 동일한 type이면 Map을 사용해라
- 각 개별 요소에 대해 적용해야 하는 로직이 있으면 objects를 사용해라

## WeakMap object

new WeakMap([iterable]) iterable : 배열 또는 요소가 key-value인 다른 iterable객체.

- WeakMap객체는 object만을 키로 허용하고 값은 임의의 값을 허용하는 key-value형태의 집합이다. key로 primitive데이터나 Symbol객체 역시 안된다.
- 키가 가지고 있는 객체에 대한 참조는 Garbage Collection의 수거 대상이 되는 약한 참조를 의미한다.
- Map과 다른부분은 WeakMap의 키들은 열거형이 아니다.(키의 목록을 제시하는 메서드가 없다) 해당 메서드가 있으면 gc의 상태 결과에 따라 키 목록이 달라지므로 비결정성을 야기한다.
- weakmap에서는 set(), get(), has(), delete()메서드만 제공을 한다.

let wm1 = new WeakMap(), … wm2 = new WeakMap(), … wm3 = new WeakMap(); undefined

let o1 = {}, … o2 = function(){}, … o3 = window; ReferenceError: window is not defined

wm1.set(o1, 37); WeakMap { [items unknown] } wm1.set(o2, “azerty”); WeakMap { [items unknown] } wm2.set(o1, o2); // 값은 무엇이든 될 수 있음, 객체 또는 함수 포함 WeakMap { [items unknown] } wm2.set(o3, undefined); ReferenceError: o3 is not defined wm2.set(wm1, wm2); // 키와 값은 어떤 객체든 될 수 있음. 심지어 WeakMap도! WeakMap { [items unknown] }

wm1.get(o2); // “azerty” ‘azerty’ wm2.get(o2); // undefined, wm2에 o2에 대한 키가 없기에 undefined wm2.get(o3); // undefined, 이게 설정값이기에 ReferenceError: o3 is not defined

wm1.has(o2); // true true wm2.has(o2); // false false wm2.has(o3); // true (값 자체가 ‘undefined’이더라도) ReferenceError: o3 is not defined

wm3.set(o1, 37); WeakMap { [items unknown] } wm3.get(o1); // 37 37

wm1.has(o1); // true true wm1.delete(o1); true wm1.has(o1); // false false ```

Set

//구문
new Set([iterable]);
  • set은 값들의 집합이다. 입력된 순서에 따라 저장된 요소를 반복처리할 수 있다.
  • set은 중복을 허용 안한다.
var mySet = new Set();

mySet.add(1); // Set { 1 }
mySet.add(5); // Set { 1, 5 }
mySet.add(5); // Set { 1, 5 }
mySet.add('some text'); // Set { 1, 5, 'some text' }
var o = {a: 1, b: 2};
mySet.add(o);

mySet.add({a: 1, b: 2}); // o와 다른 객체를 참조하므로 괜찮음

mySet.has(1); // true
mySet.has(3); // false, 3은 set에 추가되지 않았음
mySet.has(5);              // true
mySet.has(Math.sqrt(25));  // true
mySet.has('Some Text'.toLowerCase()); // true
mySet.has(o); // true

mySet.size; // 5

mySet.delete(5); // set에서 5를 제거함
mySet.has(5);    // false, 5가 제거되었음

mySet.size; // 4, 방금 값을 하나 제거했음
console.log(mySet);// Set {1, "some text", Object {a: 1, b: 2}, Object {a: 1, b: 2}}

set과 배열의 관계

> let mySet = new Set();
undefined
> mySet.add(1);
Set { 1 }
> mySet.add(3);
Set { 1, 3 }
> mySet.add(5);
Set { 1, 3, 5 }
> mySet.add(7);
Set { 1, 3, 5, 7 }
> let arr = Array.from(mySet);
> let arr2 = [1,2,3,4,5,6,7];
undefined
> mySet2 = new Set(arr2);
Set { 1, 2, 3, 4, 5, 6, 7 }
  • Array.from 또는 spread operator를 통해 Set객체를 가지고 Array를 생성할 수 있다.
  • mySet = new Set(Array);를 통해 set을 만들면 배열에 있던 중복된 요소들은 제거가 된다.

배열과 Set의 비교

  • indexOf메서드를 통해 배열에 특정요소가 있는지 비교하는것은 느리다.
  • 배열에서는 해당 요소를 잘라내는 반면 Set객체는 해당요소를 삭제한다.
  • NaN은 배열에서 indexOf로 찾을 수 없다.
  • Set은 값의 유일성을 보장하므로 직접 요소의 중복성을 찾을 필요가 없다.

weakSet

  • weakset도 weakmap과 마찬가지로 열거를 할 수 없다.
  • weakset은 객체의 집합이여서 객체만 저장할 수 있다. 특정 type의 값이 저장이 안된다.
  • weakset은 약한 참조를 가진다. gc의 수거대상이다.
  • weakset은 사용사례가 제한이 되어있는데, 메모리 누수가 발생되지 않기때문에 안전하게 DOM요소를 키로 저장할 수 있다.
Written on July 17, 2019