다음과 같은 두 개의 객체가 있다고 가정해 보겠습니다.
var object1 = { firstName: "David" };
var object2 = { firstName: "David" };겉보기에는 두 객체가 완전히 동일해 보이지만, 비교 연산자(== 또는 ===)로 비교하면 false가 반환됩니다. 그 이유는 JavaScript에서 객체는 값을 직접 비교하는 것이 아니라 참조(reference), 즉 메모리 주소를 기준으로 비교하기 때문입니다. object1과 object2는 내용은 같지만 서로 다른 메모리 공간에 저장된 별개의 객체이므로, 어떤 경우에도 같다고 판단되지 않습니다.
이 문제를 해결하려면 JSON.stringify()를 사용해 객체를 문자열로 변환한 뒤 비교하면 됩니다. 문자열은 값 자체를 기준으로 비교되기 때문에, 객체의 내용이 같다면 true를 얻을 수 있습니다.
예제 코드
아래 코드는 두 가지 방법을 모두 구현하고, 각각의 결과를 출력합니다.
var object1 = { firstName: "David" };
var object2 = { firstName: "David" };
if (object1 == object2)
console.log("== 연산자 사용 결과 ==> true");
else
console.log("== 연산자 사용 결과 ==> false");
if (JSON.stringify(object1) == JSON.stringify(object2))
console.log("JSON.stringify() 사용 결과 ==> true");
else
console.log("JSON.stringify() 사용 결과 ==> false");위 프로그램을 실행하려면 Node.js 환경에서 다음 명령어를 입력합니다.
node fileName.js
여기서는 파일 이름이 demo224.js라고 가정하겠습니다.
실행 결과
실행 결과는 다음과 같습니다.
PS C:\Users\Amit\JavaScript-code> node demo224.js == 연산자 사용 결과 ==> false JSON.stringify() 사용 결과 ==> true
주의할 점: JSON.stringify()의 한계
JSON.stringify()를 이용한 비교는 간편하지만 몇 가지 한계가 있습니다.
- 키 순서에 민감합니다.
{ a: 1, b: 2 }와{ b: 2, a: 1 }은 내용이 같아도 문자열 변환 결과가 달라 false를 반환합니다. - undefined, 함수, 심볼 속성은 무시됩니다. 해당 값들이 포함된 객체는 기대와 다른 결과를 낼 수 있습니다.
- 순환 참조가 있는 객체는 오류가 발생합니다.
따라서 단순한 평면(flat) 객체 비교에는 JSON.stringify()가 유용하지만, 중첩 구조가 복잡하거나 키 순서가 불안정한 객체를 다룰 때는 Lodash의 _.isEqual() 같은 전용 깊은 비교(deep equality) 유틸리티를 사용하는 것이 더 안전합니다.