⚖️ 동일성 vs 동등성: 차이점은 무엇일까요?
쉽게 설명하자면
- 동일성(Identity): 두 변수가 정확히 같은 객체를 가리키고 있나요? (참조 비교)
- 동등성(Equality): 두 객체의 내용이 논리적으로 같은가요? (값 비교)
🔢 자바스크립트의 비교 연산자
자바스크립트에서는 세 가지 비교 방법을 제공합니다
1. == (동등 연산자)
- 값을 비교하지만, 타입 변환을 수행합니다 (타입이 달라도 값이 같으면 true)
- 느슨한 비교(loose equality)라고도 합니다
2. === (일치 연산자)
- 값과 타입 모두 비교합니다 (타입과 값이 모두 같아야 true)
- 엄격한 비교(strict equality)라고도 합니다
3. Object.is() (ES6에서 도입)
- ===와 비슷하지만 몇 가지 특수 케이스를 다르게 처리합니다
🧩 기본 타입(Primitive) 비교하기
기본 타입(문자열, 숫자, 불리언 등)의 경우 비교가 비교적 직관적입니다
// 문자열 비교
console.log("hello" == "hello"); // true
console.log("hello" === "hello"); // true
// 숫자 비교
console.log(5 == 5); // true
console.log(5 === 5); // true
console.log(5 == "5"); // true (타입 변환 발생!)
console.log(5 === "5"); // false (타입이 다름)
🏠 객체(Object) 비교하기
객체 비교에서 진정한 차이가 드러납니다
// 객체 비교
const apple1 = { weight: 100 };
const apple2 = { weight: 100 };
const apple3 = apple1;
console.log(apple1 == apple2); // false! 내용은 같지만 다른 객체
console.log(apple1 === apple2); // false! 내용은 같지만 다른 객체
console.log(apple1 == apple3); // true! 같은 객체를 참조
console.log(apple1 === apple3); // true! 같은 객체를 참조
기억하세요! 자바스크립트에서 객체 비교는 참조(reference)를 비교합니다. 내용이 똑같아도 다른 객체라면 ==와 === 모두 false를 반환합니다! 🤯
🧠 객체의 내용 비교하기: 동등성 확인
자바스크립트에는 자바의 equals() 메소드 같은 기본 메소드가 없습니다. 대신, 내용을 비교하려면
방법 1: JSON 변환 (간단하지만 제한적)
const isEqual = (obj1, obj2) =>
JSON.stringify(obj1) === JSON.stringify(obj2);
console.log(isEqual(apple1, apple2)); // true
이 방법은 간단하지만 함수, 순환 참조, 특수 객체 등을 처리할 수 없습니다.
방법 2: 직접 비교 함수 만들기
function isAppleEqual(apple1, apple2) {
return apple1 && apple2 && apple1.weight === apple2.weight;
}
console.log(isAppleEqual(apple1, apple2)); // true
방법 3: 라이브러리 사용 (lodash 등)
const _ = require('lodash');
console.log(_.isEqual(apple1, apple2)); // true
🧵 문자열: 특별한 경우
자바스크립트에서 문자열 리터럴은 동일한 문자열을 재사용할 수 있지만, new String()으로 생성하면 항상 새 객체가 됩니다:
const str1 = "안녕하세요";
const str2 = "안녕하세요";
const str3 = new String("안녕하세요");
console.log(str1 === str2); // true (같은 문자열 리터럴)
console.log(str1 === str3); // false (객체와 기본 타입)
console.log(str1 === str3.valueOf()); // true (값 비교)
🔢 숫자 래퍼 객체(Number): 자바스크립트 스타일
const num1 = 123;
const num2 = 123;
const num3 = new Number(123);
console.log(num1 === num2); // true (기본 타입 비교)
console.log(num1 === num3); // false (객체와 기본 타입)
console.log(num1 === num3.valueOf()); // true (값 비교)
🚀 실전 팁: Node.js 백엔드 개발자를 위한 비교 가이드
- 기본 타입(Primitive) 비교: === 사용 (타입 안전성)
- 객체 참조 비교: === 사용 (동일성 체크)
- 객체 내용 비교
- 간단한 객체: JSON.stringify 또는 커스텀 함수
- 복잡한 객체: lodash의 _.isEqual 같은 라이브러리
- 데이터베이스 ID 비교: 문자열로 변환 후 === 비교
🔍 MongoDB ID 비교 예제
Node.js와 MongoDB를 함께 사용할 때 자주 마주치는 상황입니다:
// MongoDB ObjectId 비교 (실제로는 객체)
const id1 = new ObjectId('507f1f77bcf86cd799439011');
const id2 = new ObjectId('507f1f77bcf86cd799439011');
console.log(id1 === id2); // false! 다른 객체
console.log(id1.equals(id2)); // true! MongoDB는 equals() 제공
console.log(id1.toString() === id2.toString()); // true! 문자열 변환
🎯 요약: 무엇을 사용해야 할까요?
- 기본적으로 === 사용하기 (더 안전하고 예측 가능)
- 객체 비교는 내용 비교 함수나 라이브러리 사용하기
- ==는 특별한 이유가 있을 때만 사용하기
동일성과 동등성에 대해서 설명해주세요.
동일성과 동등성은 객체를 비교할 때 중요한 개념입니다. 자바에서는 이 두 개념을 equals() 메서드와 == 연산자를 통해 구분할 수 있습니다.
equals()와 ==의 차이는 무엇인가요?
equals()는 객체의 내용을 비교하는 반면, ==는 객체의 참조(레퍼런스)를 비교합니다. 따라서 두 객체의 내용이 같더라도 서로 다른 객체라면 equals()는 true를 반환할 수 있지만, ==는 false를 반환합니다.
동등성(Equality)은 뭔가요?
동등성은 논리적으로 객체의 내용이 같은지를 비교하는 개념입니다. 자바에서는 equals() 메서드를 사용하여 객체의 동등성을 비교합니다. Apple 클래스를 예시로 보면, Object.equals 메서드를 오버라이딩하여 객체의 실제 데이터를 비교하도록 했습니다. 그래서 apple과 anotherApple은 다른 객체이지만, 무게가 같기 때문에 동등성 비교 결과 true가 반환됩니다.
public class Apple {
private final int weight;
public Apple(int weight) {
this.weight = weight;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Apple apple = (Apple) o;
return weight == apple.weight;
}
@Override
public int hashCode() {
return Objects.hashCode(weight);
}
public static void main(String[] args) {
Apple apple = new Apple(100);
Apple anotherApple = new Apple(100);
System.out.println(apple.equals(anotherApple)); // true
}
}
왜 equals() 메서드를 오버라이딩 했나요?
public class Object {
...
public boolean equals(Object obj) {
return (this == obj);
}
...
}
Object 클래스의 equals() 메서드는 == 연산자를 사용하여 동일성을 비교합니다. 그리고 모든 클래스는 Object 클래스를 상속하여 동일성 비교를 기본으로 동작하기 때문에, 동등성 비교가 필요한 클래스에서 필요에 맞게 equals & hashCode 메서드를 오버라이딩해야 합니다.
동일성(Identity)은 뭔가요?
동일성은 두 객체가 메모리 상에서 같은 객체인지 비교하는 개념입니다. 자바에서는 == 연산자를 사용하여 객체의 동일성을 비교합니다. == 연산자는 객체의 레퍼런스(참조)를 비교하므로, 두 변수가 동일한 객체를 가리키고 있는지를 확인합니다.
public static void main(String[] args) {
Apple apple1 = new Apple(100);
Apple apple2 = new Apple(100);
Apple apple3 = apple1;
System.out.println(apple1 == apple2); // false
System.out.println(apple1 == apple3); // true
}
apple1과 apple2는 참조가 다르기 때문에 == 연산 결과 false가 반환되지만, apple1의 참조를 가지는 apple3은 == 연산 결과 true를 반환합니다.
String은 객체인데 == 비교해도 되던데 어떻게 된건가요?
문자열 리터럴은 문자열 상수 풀(String Constant Pool) 에 저장되기 때문에, 동일한 문자열 리터럴을 참조하면 == 연산자가 true를 반환할 수 있습니다. 하지만 new 키워드를 사용하여 문자열을 생성하면 새로운 객체가 생성되므로 == 연산자가 false를 반환할 수 있습니다. 따라서 문자열 비교 시 항상 equals() 메서드를 사용한 동등성 비교를 하는 것이 좋습니다.
public class StringComparison {
public static void main(String[] args) {
String str1 = "안녕하세요";
String str2 = "안녕하세요";
String str3 = new String("안녕하세요");
// 동일성 비교
System.out.println(str1 == str2); // true
System.out.println(str1 == str3); // false
// 동등성 비교
System.out.println(str1.equals(str2)); // true
System.out.println(str1.equals(str3)); // true
}
}
// String.class equals 오버라이딩 되어있음.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
return (anObject instanceof String aString)
&& (!COMPACT_STRINGS || this.coder == aString.coder)
&& StringLatin1.equals(value, aString.value);
}
Integer 같은 래퍼 클래스는 어떻게 비교하나요?
래퍼 클래스도 객체이기 때문에 == 연산자는 참조를 비교합니다. 값 비교를 원할 경우 equals() 메서드를 사용해야 합니다. 다만, 자바는 특정 범위의 래퍼 객체를 캐싱하므로 같은 값의 Integer 객체가 같은 참조를 가질 수 있습니다(-128 ~ 127). 하지만 일반적으로 equals()를 사용하는 것이 안전합니다.
'1일 1CS(Computer Science)' 카테고리의 다른 글
자바스크립트 호이스팅에 대해서 설명해주세요. (0) | 2025.04.09 |
---|---|
equals와 hashCode는 왜 함께 재정의해야 할까요? (0) | 2025.04.08 |
리액트의 Render Phase와 Commit Phase (0) | 2025.04.08 |
리액트의 Strict Mode에 대해서 설명해주세요. (0) | 2025.04.07 |
인터넷 창에 www.google.com를 입력하면 무슨 일이 일어나는지 설명해주세요. (0) | 2025.04.07 |