함정 시리즈

[JavaScript] Set.prototype.add()의 함정

노새두마리 2023. 11. 7. 22:24
Set.prototype.add()는 Array.prototype.push()와 달리 오직 하나의 전달인자만을 추가할 수 있습니다.

1. 메서드 호출 구문

mySet.add(value);

// 예시
mySet.add(1);
mySet.add('hi');

// 잘못된 예시
mySet.add(1, 'hi'); // 집합에는 1만 추가되며, 'hi'는 무시됩니다.
arr.push(element1[, ...[, elementN]]);

// 예시
arr.push(1);
arr.push(1, 'hi', [0]);

2. 전달인자 개수

메서드 전달인자 개수
Set.prototype.add 1
Array.prototype.push N

3. 전달인자를 생략한 경우

const mySet = new Set();
mySet.add();
mySet; // {undefined}

집합은 전달인자가 없을 시 undefined가 추가됩니다.

 

const arr = [];
arr.push();
arr; // []

배열의 경우, 전달인자가 없으면 아무것도 추가되지 않습니다.

 


4. 스프레드 문법

집합과 배열 모두 스프레드 문법을 사용하여 자료형이 가진 값들을 전개시킬 수 있습니다.

 

하지만 위에서 살펴본 특성들로 인해 집합 자료형에 값을 '추가'할 때에는 스프레드 문법을 사용해서는 안 됩니다.

const mySet = new Set([4]);
const arr = [1, 2, 3];

mySet.add(...arr);
mySet; // {4, 1}

위에서 살펴본 대로 집합에는 오직 하나의 값만 추가되기 때문이죠.

 

배열의 경우, 배열을 순회하면서 요소를 하나씩 add하는 방식으로 집합에 값을 추가할 수 있습니다.

arr.forEach(el => mySet.add(el));

 

집합과 집합을 합치기 위해서는 우선 배열을 새롭게 구성한 뒤 집합을 새롭게 선언할 필요가 있습니다.

const mySet = new Set([4]);
const arr = [1, 2, 3];

const newSet = new Set([...mySet, ...arr]);
newSet; // {4, 1, 2, 3}
const mySet = new Set([1, 5]);
const anotherSet = new Set([1, 2, 3, 4]);

const newSet = new Set([...mySet, ...anotherSet]);
newSet; // {1, 5, 2, 3, 4}

함정에 빠진 후기

Set.prototype.add는 값이 오직 하나만 추가된다는 사실을 알지 못하고 여러 집합을 하나의 집합에 집계하는 방식으로 사용하려고 하였으나 정상적으로 결과가 추가되지 않으며 헤매게 되었습니다. 이렇게 코드 에디터의 인텔리센스가 얼마나 유용한지 깨닫습니다...

 

VS Code - 타입 정의 확인 가능

 

타입스크립트 플레이그라운드 - 타입 오류 표시

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Set/add

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/push