자바스크립트에서 객체 비교
왜 같아 보이는 두 개의 객체가 다른 것일까?
let person1 = {
name: "홍길동",
age: 30,
gender: "남자",
}
let person2 = {
name: "홍길동",
age: 30,
gender: "남자",
}
console.log(person1 === person2) // 결과는 false
person1과 person2는 모두 이름이 '홍길동', 나이가 '30', 성별이 '남자'인 사람을 나타내고 있다. 그런데 person1과 person2를 비교하면 'false'가 나온다.
컴퓨터 내부에는 메모리라고 부르는 공간이 있는데, 이곳에 모든 정보가 저장된다.
객체를 만들 때마다 컴퓨터 메모리의 새로운 공간에 그 정보가 저장되게 된다. 따라서 우리가 위 코드에서 만든 person1과 person2, 즉 '홍길동'을 나타내는 두 개의 객체도 각각 다른 곳에 저장된다.
그래서 자바스크립트에서 두 개의 객체를 비교할 때, 컴퓨터는 그들이 가진 정보(속성과 값)을 직접 비교하지 않는다. 대신 각각 어디에 위치하고 있는지(메모리 주소)만 확인한다.
따라서 person1과 person2 가 동일한 정보를 가지고 있어도, 이들은 서로 다른 메모리 공간에 위치하므로 자바스크립트는 이들을 '다르다'고 판단하는 것이다.
자바스크립트에서 객체의 내용을 비교하는 방법 1
JSON.stringify를 사용하여 객체를 문자열로 변환한 후 비교
let person1 = {
name: "홍길동",
age: 30,
gender: "남자",
}
let person2 = {
name: "홍길동",
age: 30,
gender: "남자",
}
console.log(JSON.stringify(person1) === JSON.stringify(person2)) // 결과는 true
주의할 점
속성의 순서가 다르면 같은 객체라도 다르게 판단된다.
예를 들어, {name:"홍길동", age:30}와 {age:30, name:"홍길동"}는 JSON.stringify 후 비교하면 다른 것으로 판별된다.
JSON.stringify는 함수나 undefined 값을 가진 속성을 제외시킨다. 따라서 이런 값을 포함한 객체를 비교할 때는 부정확한 결과가 나올 수 있다.
자바스크립트에서 객체의 내용을 비교하는 방법 2
모든 속성과 값을 직접 비교하는 것이다. 예를 들어, 아래와 같이 'name', 'age', 'gender' 속성을 가진 두 사람 객체를 비교하는 함수를 만들 수 있다.
function isSamePerson(person1, person2) {
return person1.name === person2.name &&
person1.age === person2.age &&
person1.gender === person2.gender;
}
let persons1 = {
name: "홍길동",
age: 30,
gender: "남자",
}
let persons2 = {
name: "홍길동",
age: 30,
gender: "남자",
}
console.log(isSamePerson(persons1, persons2)); // 결과는 true
위 함수 isSamePerson은 두 사람 객체가 동일한 'name', 'age', 'gender' 값을 가지고 있는지 확인한다.
문제점
하지만 이 방법은 몇 가지 문제점이 있다.
해결 방법
따라서 lodash와 같은 자바스크립트 라이브러리에서 제공하는 _.isEqual 함수를 사용하여 쉽게 객체의 내용을 비교한다.
const _ = require('lodash');
let persons1 = {
name: "홍길동",
age: 30,
gender: "남자",
}
let persons2 = {
name: "홍길동",
age: 30,
gender: "남자",
}
console.log(_.isEqual(persons1, persons2)); // 결과는 true
위 코드에서 _.isEqual 함수는 두 개의 모든 속성과 값들을 재귀적으로(recursively) 비교하여 그들이 완전히 동일한지 확인한다.
이렇게 하면, 쉽게 객체의 내용을 비교하고, 동일한지 아닌지를 판단할 수 있다.