본문 바로가기
지금, 개발하기/Javascript

javascript] 객체의 비교

by Seaco :) 2023. 5. 19.

 

JavaScript에서 객체를 비교하려고 한다면 몇가지 주의해야 할 점이 있다. 
다른 변수들과 달리 객체참조 타입이기 때문에 값이 아닌 메모리 주소를 비교한다.  따라서 두 개의 객체를 단순히 == 또는 === 연산자로 비교하면 엉뚱한 값이 나올 수 있다. 아래 예시를 살펴보자 

1. 문제점 

1. 참조비교 
아래 예시를 보면 두 객체가 동일한 속성을 가지고 있지만 다른 메모리 주소를 가리키고 있기때문에 비교 결과가 false가 나온다. 

const obj1 = { name: 'Kim' };
const obj2 = { name: 'Kim' };
console.log(obj1 == obj2); // false
console.log(obj1 === obj2); // false
// obj1과 obj2는 동일한 속성을 가지고 있지만, 각각 다른 객체로 다른 참조값을 가지고 있기때문에 결과가 false로 나온다




2. 얕은 비교
또한 객체를 == 또는 === 연산자로 비교하면 객체의 내부 속성까지 재귀적으로 비교하지 않기때문에 비교 결과가 다르게 나온다.  객체를 비교할 때는 내부까지 깊게 비교하여야한다.

const obj1 = { name: 'Kim', age: 20 };
const obj2 = { name: 'Kim', age: 20 };
console.log(obj1 == obj2); // false
console.log(obj1 === obj2); // false
console.log(obj1.name === obj2.name && obj1.age === obj2.age); // true
// 위의 예제에서 obj1과 obj2는 객체 전체를 비교하면 false가 나오지만 개별 속성을 비교하면 true가 나온다



따라서, 객체를 비교할 때는 객체의 속성을 비교하는 방법을 사용해야 한다. 

2. 해결방법 

deepEqual(obj1, obj2) {

            // 두 객체의 타입을 비교
            if (typeof obj1 !== typeof obj2) {
                return false;
            }

            // 객체의 타입이 'object'인 경우 개별 속성을 비교
            if (typeof obj1 === 'object' && obj1 !== null && obj2 !== null) {
                const keys1 = Object.keys(obj1);
                const keys2 = Object.keys(obj2);

                // 속성 개수가 다른 경우 false를 반환
                if (keys1.length !== keys2.length) {
                return false;
                }

                // 속성의 값들을 재귀적으로 비교
                for (let key of keys1) {
                if (!deepEqual(obj1[key], obj2[key])) {
                    return false;
                }
                }

                return true;
            }

            // 타입이 'object'가 아닌경우엔 단순히 값 비교를 수행
            return obj1 === obj2;
        }



이 외에도 Lodash나 Ramda와 같은 라이브러리를 사용하면 객체를 깊은 수준까지 비교하는 함수를 제공받을 수 있다.