JavaScript Set에서 객체 검색하기
JavaScript의 Set 클래스는 특정 집합 객체 안에 요소가 존재하는지 확인할 수 있는 has() 메서드를 제공합니다. 숫자나 문자열 같은 원시 값뿐만 아니라 객체도 Set에 저장할 수 있으며, 저장된 객체를 검색할 때도 동일한 메서드를 사용합니다.
다만 객체를 검색할 때는 한 가지 중요한 규칙이 있습니다. 바로 해당 객체의 참조(reference)를 그대로 전달해야 한다는 점입니다. JavaScript에서 객체는 값 자체가 아니라 메모리상의 참조 주소로 비교되기 때문에, 내용이 완전히 동일하더라도 생성 시점이 다른 별개의 객체는 서로 다른 것으로 취급됩니다.
예를 들어 { name: "John" }이라는 객체를 두 번 만들면 사람 눈에는 똑같아 보이지만, 두 객체는 서로 다른 메모리 주소를 가지므로 Set 입장에서는 전혀 다른 개체입니다.
예제 코드
let mySet = new Set();
let myObj = { name: "John" };
mySet.add(1);
mySet.add(3);
mySet.add("a");
mySet.add(myObj);
console.log(mySet);
// 저장했던 객체의 참조로 검색 → true
console.log(mySet.has(myObj));
// 내용이 같은 새로운 객체로 검색 → false
console.log(mySet.has({ name: "John" }));
실행 결과
Set { 1, 3, 'a', { name: 'John' } }
true
false
위 결과에서 알 수 있듯이, Set에 직접 추가했던 myObj의 참조로 검색하면 true가 반환되지만, 같은 내용을 가진 새로운 객체 리터럴로 검색하면 false가 반환됩니다.
내용 기반으로 객체를 찾아야 할 때의 대안
객체의 참조가 아닌 내용을 기준으로 검색하고 싶다면 다음과 같은 방법을 고려할 수 있습니다.
- 동일한 참조 재사용: Set에 추가한 객체 변수를 코드 전체에서 그대로 유지하고 재사용합니다.
- Map 활용: 키를 기준으로 값을 조회해야 하는 상황이라면 Set 대신
Map을 사용하는 것이 더 적합합니다. - 문자열 직렬화:
JSON.stringify()로 객체를 문자열로 변환한 뒤 Set에 저장하면 내용 기반 비교가 가능합니다. 단, 속성 순서가 다르면 다른 문자열이 되므로 주의해야 합니다.
정리하면, JavaScript의 Set은 객체를 참조 단위로 관리합니다. has() 메서드를 사용할 때는 이러한 참조 비교 방식을 항상 염두에 두어야 의도치 않은 false 반환을 피할 수 있습니다.