React의 useEffect()와 useMemo() Hooks를 살펴보면서, 우리는 의존성 배열의 변화를 감지하는 areHookInputsEqual
함수를 발견했습니다. 이 함수의 핵심에는 Object.is()
메서드가 있었죠. 이 흥미로운 발견을 통해 우리는 JavaScript에서의 정확한 동등 비교가 얼마나 중요한지 알 수 있었습니다. 그렇다면 이 Object.is()
메서드에 대해 더 자세히 알아볼까요?
useEffect와 useMemo에서 사용되는 areHookInputsEqual
함수를 다시 한번 살펴봅시다:
function areHookInputsEqual(
nextDeps: Array<mixed>,
prevDeps: Array<mixed> | null,
) {
if (prevDeps === null) {
return false;
}
for (let i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
if (Object.is(nextDeps[i], prevDeps[i])) {
continue;
}
return false;
}
return true;
}
여기서 우리는 Object.is()
가 의존성 배열의 각 요소를 비교하는 데 사용되는 것을 볼 수 있습니다. 그렇다면 이 Object.is()
는 정확히 무엇이고, 왜 React는 이를 선택했을까요?
Object.is()
는 ECMAScript 6에서 도입된 메서드로, 두 값이 같은지 판단합니다. 이 메서드는 ===
(엄격한 동등 연산자)와 유사하지만, 몇 가지 특별한 경우에 다른 결과를 반환합니다.
===
와 유사하지만 NaN
과 ±0
을 처리하는 방식이 다릅니다.Object.is(value1, value2)
는 다음과 같은 알고리즘으로 동작합니다:
undefined
이면 true
를 반환합니다.null
이면 true
를 반환합니다.true
또는 모두 false
이면 true
를 반환합니다.true
를 반환합니다.true
를 반환합니다.+0
이면 true
를 반환합니다.-0
이면 true
를 반환합니다.NaN
이면 true
를 반환합니다.true
를 반환합니다.false
를 반환합니다.// 기본 타입
Object.is(undefined, undefined); // true
Object.is(null, null); // true
Object.is(true, true); // true
Object.is(false, false); // true
Object.is('hello', 'hello'); // true
Object.is(42, 42); // true
Object.is(NaN, NaN); // true
// 객체
const obj = { a: 1 };
Object.is(obj, obj); // true
// 특별한 경우
Object.is(0, 0); // true
Object.is(-0, -0); // true
// 다른 타입
Object.is(42, '42'); // false
Object.is(true, 1); // false
Object.is(null, undefined); // false
// 다른 값
Object.is('hello', 'world'); // false
Object.is(42, 43); // false
// 객체
Object.is({}, {}); // false
Object.is([], []); // false
// 특별한 경우
Object.is(0, -0); // false
Object.is()
는 NaN
과 ±0
을 처리하는 방식에서 ===
와 다릅니다:
// NaN
Object.is(NaN, NaN); // true
NaN === NaN; // false
// +0과 -0
Object.is(0, -0); // false
0 === -0; // true
이러한 차이는 특정 수학적 연산이나 정밀한 비교가 필요한 경우에 중요할 수 있습니다.
useEffect(() => {
// 부수 효과
}, [dependency]); // 여기서 dependency의 변화를 Object.is()로 감지
+0
와 -0
을 구분해야 하는 경우에 유용합니다.function divideByZero(x) {
const result = x / 0;
if (Object.is(result, Infinity)) {
return "양의 무한대";
} else if (Object.is(result, -Infinity)) {
return "음의 무한대";
}
}
NaN
을 정확히 비교해야 할 때 사용합니다.function isNaN(value) {
return Object.is(value, NaN);
}
React Hooks의 내부 구현을 통해 발견한 Object.is()
는 JavaScript에서 가장 엄격하고 정확한 동등 비교 방법을 제공합니다. 특히 NaN
과 ±0
의 비교에서 독특한 특성을 보여주며, 이는 React와 같은 라이브러리에서 정확한 상태 비교를 위해 중요합니다.
개발자로서 우리는 이러한 미묘한 차이를 이해하고, 상황에 따라 적절한 비교 방법을 선택해야 합니다. Object.is()
의 특성을 잘 이해하고 활용한다면, React 애플리케이션뿐만 아니라 일반적인 JavaScript 프로그래밍에서도 더욱 정확하고 예측 가능한 코드를 작성할 수 있을 것입니다.