두 개의 객체가 있고, 대부분의 키-값 쌍은 서로 동일하지만 하나 이상의 키에서만 값이 다르다고 가정해 보겠습니다. 이번 글에서는 두 객체를 인수로 받아 값이 다른 첫 번째 키를 반환하는 함수를 작성해 보겠습니다. 만약 모든 키의 값이 완전히 동일하다면 함수는 -1을 반환해야 합니다.
예시 객체
먼저 비교에 사용할 두 개의 샘플 객체입니다. 잘 살펴보면 salary 속성의 값만 서로 다르고 나머지 속성은 모두 같습니다.
const obj1 = {
name: 'Rahul Sharma',
id: '12342fe4554ggf',
isEmployed: true,
age: 45,
salary: 190000,
job: 'Full Stack Developer',
employedSince: 2005
};
const obj2 = {
name: 'Rahul Sharma',
id: '12342fe4554ggf',
isEmployed: true,
age: 45,
salary: 19000,
job: 'Full Stack Developer',
employedSince: 2005
};
해결 접근 방식
핵심 아이디어는 단순합니다.
Object.keys()로 첫 번째 객체의 키 목록을 구합니다.- 각 키에 대해 두 객체의 값을
!==(엄격한 불일치) 연산자로 비교합니다. - 값이 다른 키를 발견하는 즉시 해당 키를 반환하고 탐색을 중단합니다.
- 끝까지 순회했는데도 다른 키가 없다면
-1을 반환합니다.
이때 Array.prototype.find() 메서드를 활용하면 조건을 만족하는 첫 번째 요소에서 자동으로 탐색이 멈추기 때문에, "값이 다른 첫 번째 키"를 정확하고 효율적으로 얻을 수 있습니다.
전체 코드 예제
const difference = (obj1, obj2) => {
const key = Object.keys(obj1).find(key => obj1[key] !== obj2[key]);
return key ?? -1;
};
console.log(difference(obj1, obj2)); // salary
실행 결과
콘솔에 출력되는 결과는 다음과 같습니다.
salary
두 객체에서 유일하게 값이 다른 속성이 salary이므로 함수는 그 키 이름을 그대로 반환합니다. 만약 두 객체가 완전히 동일했다면 -1이 출력됩니다.
for...of 반복문을 사용한 대안
find() 대신 명령형 스타일을 선호한다면 for...of 반복문으로도 같은 로직을 구현할 수 있습니다. 조건을 만족하면 return으로 즉시 빠져나오므로 불필요한 비교를 줄일 수 있습니다.
const difference = (obj1, obj2) => {
for (const key of Object.keys(obj1)) {
if (obj1[key] !== obj2[key]) {
return key;
}
}
return -1;
};
주의할 점
forEach()안에서return은 반복문 자체를 중단하지 못합니다. 콜백 함수만 종료될 뿐 전체 순회는 계속되므로, 여러 키가 서로 다를 경우 나중에 발견된 키가 덮어써질 수 있습니다. "첫 번째" 차이를 찾으려면 위처럼find()또는for...of를 사용하는 것이 안전합니다.- 속성 값으로 중첩된 객체나 배열이 들어 있다면
!==비교는 참조(메모리 주소)만 비교합니다. 깊은 비교가 필요하다면 재귀 함수나 Lodash의isEqual같은 유틸리티를 고려하세요. - 두 객체의 키 구성 자체가 다를 수 있다면
Object.keys({ ...obj1, ...obj2 })를 기준으로 양쪽을 모두 검사하는 것이 좋습니다.
마무리
정리하면, Object.keys()와 find()를 조합하면 단 몇 줄의 코드로 두 객체 간의 첫 번째 차이점을 찾아낼 수 있습니다. 값이 다른 키가 있으면 그 키를, 모두 같으면 -1을 반환하는 이 패턴은 디버깅, 폼 변경 감지, 데이터 동기화 검증 등 다양한 실무 상황에서 유용하게 활용할 수 있습니다.